You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
vmdevirt/include/vm_lifters.hpp

96 lines
5.1 KiB

#pragma once
#include <functional>
#include <vmp_rtn.hpp>
#include <vmprofiler.hpp>
#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/IRPrintingPasses.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/PassManager.h"
#include "llvm/IR/Type.h"
#include "llvm/IR/Verifier.h"
#include "llvm/Pass.h"
namespace vm
{
class lifters_t
{
// private default constructor...
// used for singleton...
lifters_t()
{
}
using lifter_callback_t =
std::function< void( vm::vmp_rtn_t *rtn, const vm::instrs::code_block_t &vm_code_block,
const vm::instrs::virt_instr_t &vinstr, llvm::IRBuilder<> *ir_builder ) >;
static lifter_callback_t lconstq, lconstdwsxq, lconstwsxq, lconstbzxw, lconstbsxq, lconstwsxdw, lconstdw,
lconstbsxdw;
static lifter_callback_t addq, adddw, addw;
static lifter_callback_t sregq, sregdw;
static lifter_callback_t lregq, lregdw;
static lifter_callback_t pushvsp;
static lifter_callback_t readq, readdw;
static lifter_callback_t nandq, nanddw;
static lifter_callback_t shrq;
static lifter_callback_t jmp;
static lifter_callback_t lflagsq;
static lifter_callback_t vmexit;
std::map< vm::handler::mnemonic_t, lifter_callback_t * > lifters = { { vm::handler::LCONSTQ, &lconstq },
{ vm::handler::LCONSTDW, &lconstdw },
{ vm::handler::LCONSTDWSXQ, &lconstdwsxq },
{ vm::handler::LCONSTWSXQ, &lconstwsxq },
{ vm::handler::LCONSTBZXW, &lconstbzxw },
{ vm::handler::LCONSTBSXQ, &lconstbsxq },
{ vm::handler::LCONSTWSXDW, &lconstwsxdw },
{ vm::handler::LCONSTBSXDW, &lconstbsxdw },
{ vm::handler::ADDQ, &addq },
{ vm::handler::ADDDW, &adddw },
{ vm::handler::ADDW, &addw },
{ vm::handler::SHRQ, &shrq },
{ vm::handler::PUSHVSP, &pushvsp },
{ vm::handler::SREGQ, &sregq },
{ vm::handler::SREGDW, &sregdw },
{ vm::handler::LREGQ, &lregq },
{ vm::handler::LREGDW, &lregdw },
{ vm::handler::READQ, &readq },
{ vm::handler::READDW, &readdw },
{ vm::handler::NANDQ, &nandq },
{ vm::handler::NANDDW, &nanddw },
{ vm::handler::LFLAGSQ, &lflagsq },
{ vm::handler::JMP, &jmp },
{ vm::handler::VMEXIT, &vmexit } };
static llvm::Value *and_flags( vm::vmp_rtn_t *rtn, std::uint8_t byte_size, llvm::Value *result );
static llvm::Value *add_flags( vm::vmp_rtn_t *rtn, std::uint8_t byte_size, llvm::Value *lhs, llvm::Value *rhs );
static llvm::Value *shr_flags( vm::vmp_rtn_t *rtn, std::uint8_t byte_size, llvm::Value *lhs, llvm::Value *rhs,
llvm::Value *result );
public:
static lifters_t *get_instance( void )
{
static lifters_t obj;
return &obj;
}
bool lift( vm::vmp_rtn_t *rtn, const vm::instrs::code_block_t &vm_code_block,
const vm::instrs::virt_instr_t &vinstr, llvm::IRBuilder<> *ir_builder )
{
if ( vinstr.mnemonic_t == vm::handler::INVALID || lifters.find( vinstr.mnemonic_t ) == lifters.end() )
return false;
( *( lifters[ vinstr.mnemonic_t ] ) )( rtn, vm_code_block, vinstr, ir_builder );
return true;
}
};
} // namespace vm