mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-19 19:30:44 +00:00
Merge branch 'develop-evmcc' of git@github.com:imapp-pl/ethereum.git into develop-evmcc
Conflicts: evmcc/Compiler.cpp
This commit is contained in:
commit
15b945219a
14 changed files with 490 additions and 51 deletions
|
|
@ -3,8 +3,11 @@
|
|||
|
||||
#include <llvm/IR/IRBuilder.h>
|
||||
|
||||
#include <libevmface/Instruction.h>
|
||||
|
||||
#include "Memory.h"
|
||||
#include "Stack.h"
|
||||
#include "Ext.h"
|
||||
|
||||
namespace evmcc
|
||||
{
|
||||
|
|
@ -18,6 +21,7 @@ struct
|
|||
llvm::Type* word256arr;
|
||||
llvm::Type* size;
|
||||
llvm::Type* Void;
|
||||
llvm::Type* WordLowPrecision;
|
||||
} Types;
|
||||
|
||||
Compiler::Compiler()
|
||||
|
|
@ -30,6 +34,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);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -38,41 +45,212 @@ std::unique_ptr<llvm::Module> Compiler::compile(const dev::bytes& bytecode)
|
|||
using namespace llvm;
|
||||
|
||||
auto& context = getGlobalContext();
|
||||
|
||||
auto module = std::make_unique<Module>("main", context);
|
||||
IRBuilder<> builder(context);
|
||||
|
||||
// Create main function
|
||||
FunctionType* funcType = FunctionType::get(llvm::Type::getInt32Ty(context), false);
|
||||
Function* mainFunc = Function::Create(funcType, Function::ExternalLinkage, "main", module.get());
|
||||
auto mainFuncType = FunctionType::get(llvm::Type::getInt32Ty(context), false);
|
||||
auto mainFunc = Function::Create(mainFuncType, Function::ExternalLinkage, "main", module.get());
|
||||
|
||||
BasicBlock* entryBlock = BasicBlock::Create(context, "entry", mainFunc);
|
||||
auto entryBlock = BasicBlock::Create(context, "entry", mainFunc);
|
||||
builder.SetInsertPoint(entryBlock);
|
||||
|
||||
|
||||
// Init stack and memory
|
||||
auto stack = Stack(builder, module.get());
|
||||
auto memory = Memory(builder, module.get());
|
||||
|
||||
uint64_t words[] = { 1, 2, 3, 4 };
|
||||
auto val = llvm::APInt(256, 4, words);
|
||||
auto c = ConstantInt::get(Types.word256, val);
|
||||
auto ext = Ext(builder);
|
||||
|
||||
stack.push(c);
|
||||
stack.push(ConstantInt::get(Types.word256, 0x1122334455667788));
|
||||
for (auto pc = bytecode.cbegin(); pc != bytecode.cend(); ++pc)
|
||||
{
|
||||
using dev::eth::Instruction;
|
||||
|
||||
auto top = stack.top();
|
||||
stack.push(top); // dup
|
||||
stack.pop();
|
||||
auto inst = static_cast<Instruction>(*pc);
|
||||
switch (inst)
|
||||
{
|
||||
|
||||
auto index = ConstantInt::get(Types.word256, 123);
|
||||
memory.storeWord(index, c);
|
||||
case Instruction::ADD:
|
||||
{
|
||||
auto lhs = stack.pop();
|
||||
auto rhs = stack.pop();
|
||||
auto result = builder.CreateAdd(lhs, rhs);
|
||||
stack.push(result);
|
||||
break;
|
||||
}
|
||||
|
||||
memory.dump(123, 123+32);
|
||||
case Instruction::SUB:
|
||||
{
|
||||
auto lhs = stack.pop();
|
||||
auto rhs = stack.pop();
|
||||
auto result = builder.CreateSub(lhs, rhs);
|
||||
stack.push(result);
|
||||
break;
|
||||
}
|
||||
|
||||
auto index2 = ConstantInt::get(Types.word256, 123 + 16);
|
||||
auto byte = memory.loadByte(index2);
|
||||
auto result = builder.CreateZExt(byte, builder.getInt32Ty());
|
||||
builder.CreateRet(result); // should return 3
|
||||
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();
|
||||
break;
|
||||
}
|
||||
|
||||
case Instruction::PUSH1:
|
||||
case Instruction::PUSH2:
|
||||
case Instruction::PUSH3:
|
||||
case Instruction::PUSH4:
|
||||
case Instruction::PUSH5:
|
||||
case Instruction::PUSH6:
|
||||
case Instruction::PUSH7:
|
||||
case Instruction::PUSH8:
|
||||
case Instruction::PUSH9:
|
||||
case Instruction::PUSH10:
|
||||
case Instruction::PUSH11:
|
||||
case Instruction::PUSH12:
|
||||
case Instruction::PUSH13:
|
||||
case Instruction::PUSH14:
|
||||
case Instruction::PUSH15:
|
||||
case Instruction::PUSH16:
|
||||
case Instruction::PUSH17:
|
||||
case Instruction::PUSH18:
|
||||
case Instruction::PUSH19:
|
||||
case Instruction::PUSH20:
|
||||
case Instruction::PUSH21:
|
||||
case Instruction::PUSH22:
|
||||
case Instruction::PUSH23:
|
||||
case Instruction::PUSH24:
|
||||
case Instruction::PUSH25:
|
||||
case Instruction::PUSH26:
|
||||
case Instruction::PUSH27:
|
||||
case Instruction::PUSH28:
|
||||
case Instruction::PUSH29:
|
||||
case Instruction::PUSH30:
|
||||
case Instruction::PUSH31:
|
||||
case Instruction::PUSH32:
|
||||
{
|
||||
auto numBytes = static_cast<size_t>(inst) - static_cast<size_t>(Instruction::PUSH1) + 1;
|
||||
auto value = llvm::APInt(256, 0);
|
||||
for (decltype(numBytes) i = 0; i < numBytes; ++i) // TODO: Use pc as iterator
|
||||
{
|
||||
++pc;
|
||||
value <<= 8;
|
||||
value |= *pc;
|
||||
}
|
||||
auto c = builder.getInt(value);
|
||||
stack.push(c);
|
||||
break;
|
||||
}
|
||||
|
||||
case Instruction::DUP1:
|
||||
case Instruction::DUP2:
|
||||
case Instruction::DUP3:
|
||||
case Instruction::DUP4:
|
||||
case Instruction::DUP5:
|
||||
case Instruction::DUP6:
|
||||
case Instruction::DUP7:
|
||||
case Instruction::DUP8:
|
||||
case Instruction::DUP9:
|
||||
case Instruction::DUP10:
|
||||
case Instruction::DUP11:
|
||||
case Instruction::DUP12:
|
||||
case Instruction::DUP13:
|
||||
case Instruction::DUP14:
|
||||
case Instruction::DUP15:
|
||||
case Instruction::DUP16:
|
||||
{
|
||||
auto index = static_cast<uint32_t>(inst) - static_cast<uint32_t>(Instruction::DUP1);
|
||||
auto value = stack.get(index);
|
||||
stack.push(value);
|
||||
break;
|
||||
}
|
||||
|
||||
case Instruction::SWAP1:
|
||||
case Instruction::SWAP2:
|
||||
case Instruction::SWAP3:
|
||||
case Instruction::SWAP4:
|
||||
case Instruction::SWAP5:
|
||||
case Instruction::SWAP6:
|
||||
case Instruction::SWAP7:
|
||||
case Instruction::SWAP8:
|
||||
case Instruction::SWAP9:
|
||||
case Instruction::SWAP10:
|
||||
case Instruction::SWAP11:
|
||||
case Instruction::SWAP12:
|
||||
case Instruction::SWAP13:
|
||||
case Instruction::SWAP14:
|
||||
case Instruction::SWAP15:
|
||||
case Instruction::SWAP16:
|
||||
{
|
||||
auto index = static_cast<uint32_t>(inst) - static_cast<uint32_t>(Instruction::SWAP1) + 1;
|
||||
auto loValue = stack.get(index);
|
||||
auto hiValue = stack.get(0);
|
||||
stack.set(index, hiValue);
|
||||
stack.set(0, loValue);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
builder.CreateRet(ConstantInt::get(Type::getInt32Ty(context), 0));
|
||||
|
||||
return module;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,6 +13,8 @@
|
|||
#include <llvm/Support/PrettyStackTrace.h>
|
||||
#include <llvm/Support/Host.h>
|
||||
|
||||
#include "Ext.h"
|
||||
|
||||
namespace evmcc
|
||||
{
|
||||
|
||||
|
|
@ -66,6 +68,9 @@ int ExecutionEngine::run(std::unique_ptr<llvm::Module> _module)
|
|||
_module.release(); // Successfully created llvm::ExecutionEngine takes ownership of the module
|
||||
exec->finalizeObject();
|
||||
|
||||
auto ext = std::make_unique<dev::eth::ExtVMFace>();
|
||||
Ext::init(std::move(ext));
|
||||
|
||||
auto entryFunc = module->getFunction("main");
|
||||
if (!entryFunc)
|
||||
{
|
||||
|
|
|
|||
52
evmcc/Ext.cpp
Normal file
52
evmcc/Ext.cpp
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
|
||||
#include "Ext.h"
|
||||
|
||||
#include <llvm/IR/Function.h>
|
||||
#include <llvm/IR/TypeBuilder.h>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#define EXPORT __declspec(dllexport)
|
||||
#else
|
||||
#define EXPORT
|
||||
#endif
|
||||
|
||||
using namespace llvm;
|
||||
using llvm::types::i;
|
||||
using Linkage = llvm::GlobalValue::LinkageTypes;
|
||||
|
||||
namespace evmcc
|
||||
{
|
||||
|
||||
std::unique_ptr<dev::eth::ExtVMFace> g_ext;
|
||||
|
||||
void Ext::init(std::unique_ptr<dev::eth::ExtVMFace> _ext)
|
||||
{
|
||||
g_ext = std::move(_ext);
|
||||
}
|
||||
|
||||
Ext::Ext(llvm::IRBuilder<>& _builder)
|
||||
: m_builder(_builder)
|
||||
{
|
||||
auto module = m_builder.GetInsertBlock()->getParent()->getParent();
|
||||
auto&& ctx = _builder.getContext();
|
||||
|
||||
Function::Create(TypeBuilder<void(i<256>*, i<256>*), true>::get(ctx), Linkage::ExternalLinkage, "ext_store", module);
|
||||
Function::Create(TypeBuilder<void(i<256>*, i<256>*), true>::get(ctx), Linkage::ExternalLinkage, "ext_setStore", module);
|
||||
}
|
||||
|
||||
extern "C"
|
||||
{
|
||||
|
||||
EXPORT void ext_store(void* _index, void* _value)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
EXPORT void ext_setStore(void* _index, void* _value)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
22
evmcc/Ext.h
Normal file
22
evmcc/Ext.h
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
|
||||
#include <llvm/IR/IRBuilder.h>
|
||||
|
||||
#include <libevm/ExtVMFace.h>
|
||||
|
||||
namespace evmcc
|
||||
{
|
||||
|
||||
|
||||
|
||||
class Ext
|
||||
{
|
||||
public:
|
||||
Ext(llvm::IRBuilder<>& _builder);
|
||||
static void init(std::unique_ptr<dev::eth::ExtVMFace> _ext);
|
||||
|
||||
private:
|
||||
llvm::IRBuilder<>& m_builder;
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -47,12 +47,17 @@ Stack::Stack(llvm::IRBuilder<>& _builder, llvm::Module* _module)
|
|||
m_stackPush = llvm::Function::Create(funcType,
|
||||
llvm::GlobalValue::LinkageTypes::ExternalLinkage, "evmccrt_stack_push", _module);
|
||||
|
||||
m_stackTop = llvm::Function::Create(funcType,
|
||||
llvm::GlobalValue::LinkageTypes::ExternalLinkage, "evmccrt_stack_top", _module);
|
||||
|
||||
m_stackPop = llvm::Function::Create(funcType,
|
||||
llvm::GlobalValue::LinkageTypes::ExternalLinkage, "evmccrt_stack_pop", _module);
|
||||
|
||||
llvm::Type* getArgsTypes[] = {stackPtrTy, m_builder.getInt32Ty(), i256PtrTy};
|
||||
auto getFuncType = llvm::FunctionType::get(voidTy, getArgsTypes, false);
|
||||
m_stackGet = llvm::Function::Create(getFuncType,
|
||||
llvm::GlobalValue::LinkageTypes::ExternalLinkage, "evmccrt_stack_get", _module);
|
||||
|
||||
m_stackSet = llvm::Function::Create(getFuncType,
|
||||
llvm::GlobalValue::LinkageTypes::ExternalLinkage, "evmccrt_stack_set", _module);
|
||||
|
||||
m_args[0] = m_builder.CreateCall(stackCreate, "stack.ptr");
|
||||
m_args[1] = m_builder.CreateAlloca(i256Ty, nullptr, "stack.val");
|
||||
}
|
||||
|
|
@ -65,13 +70,6 @@ void Stack::push(llvm::Value* _value)
|
|||
}
|
||||
|
||||
|
||||
llvm::Value* Stack::top()
|
||||
{
|
||||
m_builder.CreateCall(m_stackTop, m_args);
|
||||
return m_builder.CreateLoad(m_args[1]);
|
||||
}
|
||||
|
||||
|
||||
llvm::Value* Stack::pop()
|
||||
{
|
||||
m_builder.CreateCall(m_stackPop, m_args);
|
||||
|
|
@ -79,18 +77,41 @@ llvm::Value* Stack::pop()
|
|||
}
|
||||
|
||||
|
||||
void debugStack(const char* op, const i256& word)
|
||||
llvm::Value* Stack::get(uint32_t _index)
|
||||
{
|
||||
std::cerr << "STACK " << std::setw(4) << std::setfill(' ') << op << ": "
|
||||
<< std::dec << word.a
|
||||
<< " HEX: " << std::hex << std::setfill('0');
|
||||
if (word.b || word.c || word.d)
|
||||
llvm::Value* args[] = {m_args[0], m_builder.getInt32(_index), m_args[1]};
|
||||
m_builder.CreateCall(m_stackGet, args);
|
||||
return m_builder.CreateLoad(m_args[1]);
|
||||
}
|
||||
|
||||
|
||||
void Stack::set(uint32_t _index, llvm::Value* _value)
|
||||
{
|
||||
m_builder.CreateStore(_value, m_args[1]); // copy value to memory
|
||||
llvm::Value* args[] = {m_args[0], m_builder.getInt32(_index), m_args[1]};
|
||||
m_builder.CreateCall(m_stackSet, args);
|
||||
}
|
||||
|
||||
|
||||
llvm::Value* Stack::top()
|
||||
{
|
||||
return get(0);
|
||||
}
|
||||
|
||||
|
||||
void debugStack(const char* _op, const i256& _word, uint32_t _index = 0)
|
||||
{
|
||||
std::cerr << "STACK " << std::setw(4) << std::setfill(' ') << _op
|
||||
<< " [" << std::setw(2) << std::setfill('0') << _index << "] "
|
||||
<< std::dec << _word.a
|
||||
<< " HEX: " << std::hex;
|
||||
if (_word.b || _word.c || _word.d)
|
||||
{
|
||||
std::cerr << std::setw(16) << word.d << " "
|
||||
<< std::setw(16) << word.c << " "
|
||||
<< std::setw(16) << word.b << " ";
|
||||
std::cerr << std::setw(16) << _word.d << " "
|
||||
<< std::setw(16) << _word.c << " "
|
||||
<< std::setw(16) << _word.b << " ";
|
||||
}
|
||||
std::cerr << std::setw(16) << word.a << "\n";
|
||||
std::cerr << std::setw(16) << _word.a << "\n";
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -114,16 +135,6 @@ EXPORT void evmccrt_stack_push(void* _stack, void* _pWord)
|
|||
stack->push_back(*word);
|
||||
}
|
||||
|
||||
EXPORT void evmccrt_stack_top(void* _stack, void* _pWord)
|
||||
{
|
||||
auto stack = static_cast<StackImpl*>(_stack);
|
||||
assert(!stack->empty());
|
||||
auto word = &stack->back();
|
||||
debugStack("top", *word);
|
||||
auto outWord = static_cast<i256*>(_pWord);
|
||||
*outWord = *word;
|
||||
}
|
||||
|
||||
EXPORT void evmccrt_stack_pop(void* _stack, void* _pWord)
|
||||
{
|
||||
auto stack = static_cast<StackImpl*>(_stack);
|
||||
|
|
@ -135,4 +146,23 @@ EXPORT void evmccrt_stack_pop(void* _stack, void* _pWord)
|
|||
*outWord = *word;
|
||||
}
|
||||
|
||||
EXPORT void evmccrt_stack_get(void* _stack, uint32_t _index, void* _pWord)
|
||||
{
|
||||
auto stack = static_cast<StackImpl*>(_stack);
|
||||
assert(_index < stack->size());
|
||||
auto word = stack->rbegin() + _index;
|
||||
debugStack("get", *word, _index);
|
||||
auto outWord = static_cast<i256*>(_pWord);
|
||||
*outWord = *word;
|
||||
}
|
||||
|
||||
EXPORT void evmccrt_stack_set(void* _stack, uint32_t _index, void* _pWord)
|
||||
{
|
||||
auto stack = static_cast<StackImpl*>(_stack);
|
||||
auto word = static_cast<i256*>(_pWord);
|
||||
assert(_index < stack->size());
|
||||
*(stack->rbegin() + _index) = *word;
|
||||
debugStack("set", *word, _index);
|
||||
}
|
||||
|
||||
} // extern "C"
|
||||
|
|
|
|||
|
|
@ -12,15 +12,18 @@ public:
|
|||
Stack(llvm::IRBuilder<>& _builder, llvm::Module* _module);
|
||||
|
||||
void push(llvm::Value* _value);
|
||||
llvm::Value* top();
|
||||
llvm::Value* pop();
|
||||
llvm::Value* top();
|
||||
llvm::Value* get(uint32_t _index);
|
||||
void set(uint32_t _index, llvm::Value* _value);
|
||||
|
||||
private:
|
||||
llvm::IRBuilder<>& m_builder;
|
||||
llvm::Value* m_args[2];
|
||||
llvm::Function* m_stackPush;
|
||||
llvm::Function* m_stackTop;
|
||||
llvm::Function* m_stackPop;
|
||||
llvm::Function* m_stackGet;
|
||||
llvm::Function* m_stackSet;
|
||||
};
|
||||
|
||||
}
|
||||
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
|
||||
1
evmcc/bytecode/push_test.evm
Normal file
1
evmcc/bytecode/push_test.evm
Normal file
|
|
@ -0,0 +1 @@
|
|||
60656107d26204a0c763026921f4640bc5588eb165372d0f1dca6e661ba1d901961c71670c55f7bc23038e3868056bc75e2d630fffff69021e19e0c9bab24000016a085d1c6e8050f0ea1c71bd6b0688be36543f3c36e638e37a6c03d41f73d55d0d482ae55555376dc76810d0fe03c91964d31c71c6f46e615dd0360c07d931663b14e38e38b16f2da3f99955a3adcf27ebb1caaaaaaa6e7014ccba6a8bb1ed35bd86bf065c71c71c2b7109491c5d4781b79c9009de6bfb8e38e38de8720414a0f6fdec81304d4c563e740bffffffffa573118427b3b4a05bc8a8a4de8459868000000000017406eb15e7331e727940d4ac54b7cdca1c71c71c71bd750567a91c9fefc96ebaa626a22f98c5e638e38e38e37a76032abd16c5b68006e15d5aa307e383f4e55555555555377701a6427bdc4f0d58eab5f48a3ec67f64e21c71c71c71c6f478080dd0a0c9b9ff2c2a0c740b06853a0a980ee38e38e38e38b17903c679cb5e8f2f9cb3b5d6652b0e7334f746faaaaaaaaaaaaa6e7a01b873815917ebb2bf3b890a1af495d6235bae3c71c71c71c71c2b7b07ae4cca96e1a55dfa49c85ad3c3e60e426b92fb8e38e38e38e38de87c036018bf074e292bcc7d6c8bea0f9699443046178bffffffffffffffa57d0e7d34c64a9c85d4460dbbca87196b61618a4bd2168000000000000000017e05b901f48a5b994d6572502bc4ea43140486666416aa1c71c71c71c71c71bd7f047889870c178fc477414ea231d70467a388fffe31b4e638e38e38e38e38e37a
|
||||
1
evmcc/bytecode/stack_test.evm
Normal file
1
evmcc/bytecode/stack_test.evm
Normal file
|
|
@ -0,0 +1 @@
|
|||
65372d0f1dca6e661925338e3e5c2b808280848184505050505050506104576108ae81819290
|
||||
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
|
||||
)
|
||||
35
evmcc/lll/push_test.lll
Normal file
35
evmcc/lll/push_test.lll
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
|
||||
(asm
|
||||
101 ;; PUSH1
|
||||
2002 ;; PUSH2
|
||||
303303 ;; PUSH3
|
||||
40444404 ;; PUSH4
|
||||
50555555505 ;; PUSH5
|
||||
60666666666606
|
||||
7777777777777777
|
||||
888888888888888888
|
||||
99999999999999999999
|
||||
10000000000000000000001
|
||||
10111111111111111111111101
|
||||
2022222222222222222222222202
|
||||
303333333333333333333333333303
|
||||
4044444444444444444444444444444404
|
||||
505555555555555555555555555555555505
|
||||
60666666666666666666666666666666666606
|
||||
7077777777777777777777777777777777777707
|
||||
808888888888888888888888888888888888888808
|
||||
90999999999999999999999999999999999999999909
|
||||
100000000000000000000000000000000000000000000001
|
||||
10111111111111111111111111111111111111111111111101
|
||||
2022222222222222222222222222222222222222222222222202
|
||||
303333333333333333333333333333333333333333333333333303
|
||||
40444444444444444444444444444444444444444444444444444404
|
||||
50555555555555555555555555555555555555555555555555555555505
|
||||
6066666666666666666666666666666666666666666666666666666666606
|
||||
707777777777777777777777777777777777777777777777777777777777707
|
||||
808888888888888888888888888888888888888888888888888888888888888808
|
||||
90999999999999999999999999999999999999999999999999999999999999999909
|
||||
100000000000000000000000000000000000000000000000000000000000000000000001
|
||||
10111111111111111111111111111111111111111111111111111111111111111111111101
|
||||
2022222222222222222222222222222222222222222222222222222222222222222222222202 ;; PUSH32
|
||||
)
|
||||
24
evmcc/lll/stack_test.lll
Normal file
24
evmcc/lll/stack_test.lll
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
|
||||
(asm
|
||||
60666666666606
|
||||
7077777777777707
|
||||
DUP1
|
||||
DUP3
|
||||
DUP1
|
||||
DUP5
|
||||
DUP2
|
||||
DUP5
|
||||
POP
|
||||
POP
|
||||
POP
|
||||
POP
|
||||
POP
|
||||
POP
|
||||
POP
|
||||
1111
|
||||
2222
|
||||
DUP2
|
||||
DUP2
|
||||
SWAP3
|
||||
SWAP1
|
||||
)
|
||||
Loading…
Reference in a new issue