mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-20 11:46: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* word256arr;
|
||||||
llvm::Type* size;
|
llvm::Type* size;
|
||||||
llvm::Type* Void;
|
llvm::Type* Void;
|
||||||
|
llvm::Type* WordLowPrecision;
|
||||||
} Types;
|
} Types;
|
||||||
|
|
||||||
Compiler::Compiler()
|
Compiler::Compiler()
|
||||||
|
|
@ -31,6 +32,9 @@ Compiler::Compiler()
|
||||||
Types.word256arr = llvm::ArrayType::get(Types.word256, 100);
|
Types.word256arr = llvm::ArrayType::get(Types.word256, 100);
|
||||||
Types.size = llvm::Type::getInt64Ty(context);
|
Types.size = llvm::Type::getInt64Ty(context);
|
||||||
Types.Void = llvm::Type::getVoidTy(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);
|
auto inst = static_cast<Instruction>(*pc);
|
||||||
switch (inst)
|
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:
|
case Instruction::POP:
|
||||||
{
|
{
|
||||||
stack.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