Preparation for multi-threading/multi-core DBT
This commit is contained in:
parent
3ea46d882b
commit
b4871ac725
2
dbt-core
2
dbt-core
|
@ -1 +1 @@
|
||||||
Subproject commit d0422e5f8df2391df372779b06c807d456a058a3
|
Subproject commit cf9679475121f85a6333970f80bb6a40a8b4a0a5
|
|
@ -74,13 +74,15 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
using vm::vm_base<ARCH>::get_reg_ptr;
|
||||||
|
|
||||||
template <typename T> inline llvm::ConstantInt *size(T type) {
|
template <typename T> inline llvm::ConstantInt *size(T type) {
|
||||||
return llvm::ConstantInt::get(getContext(), llvm::APInt(32, type->getType()->getScalarSizeInBits()));
|
return llvm::ConstantInt::get(getContext(), llvm::APInt(32, type->getType()->getScalarSizeInBits()));
|
||||||
}
|
}
|
||||||
|
|
||||||
inline llvm::Value *gen_choose(llvm::Value *cond, llvm::Value *trueVal, llvm::Value *falseVal,
|
inline llvm::Value *gen_choose(llvm::Value *cond, llvm::Value *trueVal, llvm::Value *falseVal,
|
||||||
unsigned size) const {
|
unsigned size) const {
|
||||||
return this->gen_cond_assign(cond, this->gen_ext(trueVal, size), this->gen_ext(falseVal, size));
|
return super::gen_cond_assign(cond, this->gen_ext(trueVal, size), this->gen_ext(falseVal, size));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::tuple<vm::continuation_e, llvm::BasicBlock *> gen_single_inst_behavior(virt_addr_t &, unsigned int &,
|
std::tuple<vm::continuation_e, llvm::BasicBlock *> gen_single_inst_behavior(virt_addr_t &, unsigned int &,
|
||||||
|
@ -98,55 +100,17 @@ protected:
|
||||||
|
|
||||||
void gen_trap_check(llvm::BasicBlock *bb);
|
void gen_trap_check(llvm::BasicBlock *bb);
|
||||||
|
|
||||||
|
|
||||||
|
inline llvm::Value *gen_reg_load(unsigned i, unsigned level = 0) {
|
||||||
|
return this->builder->CreateLoad(get_reg_ptr(i), false);
|
||||||
|
}
|
||||||
|
|
||||||
inline void gen_set_pc(virt_addr_t pc, unsigned reg_num) {
|
inline void gen_set_pc(virt_addr_t pc, unsigned reg_num) {
|
||||||
llvm::Value *next_pc_v = this->builder->CreateSExtOrTrunc(this->gen_const(traits<ARCH>::XLEN, pc.val),
|
llvm::Value *next_pc_v = this->builder->CreateSExtOrTrunc(this->gen_const(traits<ARCH>::XLEN, pc.val),
|
||||||
this->get_type(traits<ARCH>::XLEN));
|
this->get_type(traits<ARCH>::XLEN));
|
||||||
this->builder->CreateStore(next_pc_v, get_reg_ptr(reg_num), true);
|
this->builder->CreateStore(next_pc_v, get_reg_ptr(reg_num), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline llvm::Value *get_reg_ptr(unsigned i) {
|
|
||||||
void *ptr = this->core.get_regs_base_ptr() + traits<ARCH>::reg_byte_offset(i);
|
|
||||||
llvm::PointerType *ptrType = nullptr;
|
|
||||||
switch (traits<ARCH>::reg_bit_width(i) >> 3) {
|
|
||||||
case 8:
|
|
||||||
ptrType = llvm::Type::getInt64PtrTy(this->mod->getContext());
|
|
||||||
break;
|
|
||||||
case 4:
|
|
||||||
ptrType = llvm::Type::getInt32PtrTy(this->mod->getContext());
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
ptrType = llvm::Type::getInt16PtrTy(this->mod->getContext());
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
ptrType = llvm::Type::getInt8PtrTy(this->mod->getContext());
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
throw std::runtime_error("unsupported access with");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return llvm::ConstantExpr::getIntToPtr(
|
|
||||||
llvm::ConstantInt::get(this->mod->getContext(),
|
|
||||||
llvm::APInt(8 /*bits*/ * sizeof(uint8_t *), reinterpret_cast<uint64_t>(ptr))),
|
|
||||||
ptrType);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline llvm::Value *gen_reg_load(unsigned i, unsigned level = 0) {
|
|
||||||
// if(level){
|
|
||||||
return this->builder->CreateLoad(get_reg_ptr(i), false);
|
|
||||||
// } else {
|
|
||||||
// if(!this->loaded_regs[i])
|
|
||||||
// this->loaded_regs[i]=this->builder->CreateLoad(get_reg_ptr(i),
|
|
||||||
// false);
|
|
||||||
// return this->loaded_regs[i];
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void gen_set_pc(virt_addr_t pc) {
|
|
||||||
llvm::Value *pc_l = this->builder->CreateSExt(this->gen_const(traits<ARCH>::caddr_bit_width, (unsigned)pc),
|
|
||||||
this->get_type(traits<ARCH>::caddr_bit_width));
|
|
||||||
super::gen_set_reg(traits<ARCH>::PC, pc_l);
|
|
||||||
}
|
|
||||||
|
|
||||||
// some compile time constants
|
// some compile time constants
|
||||||
// enum { MASK16 = 0b1111110001100011, MASK32 = 0b11111111111100000111000001111111 };
|
// enum { MASK16 = 0b1111110001100011, MASK32 = 0b11111111111100000111000001111111 };
|
||||||
enum { MASK16 = 0b1111111111111111, MASK32 = 0b11111111111100000111000001111111 };
|
enum { MASK16 = 0b1111111111111111, MASK32 = 0b11111111111100000111000001111111 };
|
||||||
|
@ -224,22 +188,33 @@ private:
|
||||||
llvm::BasicBlock *bb) {
|
llvm::BasicBlock *bb) {
|
||||||
bb->setName("illegal_instruction");
|
bb->setName("illegal_instruction");
|
||||||
|
|
||||||
this->gen_sync(iss::PRE_SYNC);
|
// this->gen_sync(iss::PRE_SYNC);
|
||||||
if(this->disass_enabled){
|
// if(this->disass_enabled){
|
||||||
/* generate console output when executing the command */
|
// /* generate console output when executing the command */
|
||||||
/* generate console output when executing the command */
|
// boost::format ins_fmter("DB x%1$d");
|
||||||
boost::format ins_fmter("DB x%1$d");
|
// ins_fmter % (uint64_t)instr;
|
||||||
ins_fmter % (uint64_t)instr;
|
// std::vector<llvm::Value*> args {
|
||||||
std::vector<llvm::Value*> args {
|
// this->core_ptr,
|
||||||
this->core_ptr,
|
// this->gen_const(64, pc.val),
|
||||||
this->gen_const(64, pc.val),
|
// this->builder->CreateGlobalStringPtr(ins_fmter.str()),
|
||||||
this->builder->CreateGlobalStringPtr(ins_fmter.str()),
|
// };
|
||||||
};
|
// this->builder->CreateCall(this->mod->getFunction("print_disass"), args);
|
||||||
this->builder->CreateCall(this->mod->getFunction("print_disass"), args);
|
// }
|
||||||
}
|
// pc = pc + ((instr & 3) == 3 ? 4 : 2);
|
||||||
|
// this->gen_raise_trap(0, 2); // illegal instruction trap
|
||||||
|
// this->gen_sync(iss::POST_SYNC); /* call post-sync if needed */
|
||||||
|
// this->gen_trap_check(this->leave_blk);
|
||||||
|
// return std::make_tuple(iss::vm::BRANCH, nullptr);
|
||||||
|
// this->gen_sync(iss::PRE_SYNC);
|
||||||
|
this->builder->CreateStore(this->builder->CreateLoad(get_reg_ptr(traits<ARCH>::NEXT_PC), true),
|
||||||
|
get_reg_ptr(traits<ARCH>::PC), true);
|
||||||
|
this->builder->CreateStore(
|
||||||
|
this->builder->CreateAdd(this->builder->CreateLoad(get_reg_ptr(traits<ARCH>::ICOUNT), true),
|
||||||
|
this->gen_const(64U, 1)),
|
||||||
|
get_reg_ptr(traits<ARCH>::ICOUNT), true);
|
||||||
|
if (this->debugging_enabled()) this->gen_sync(iss::PRE_SYNC);
|
||||||
pc = pc + ((instr & 3) == 3 ? 4 : 2);
|
pc = pc + ((instr & 3) == 3 ? 4 : 2);
|
||||||
|
this->gen_raise_trap(0, 2); // illegal instruction trap
|
||||||
this->gen_raise_trap(0, 2);
|
|
||||||
this->gen_sync(iss::POST_SYNC); /* call post-sync if needed */
|
this->gen_sync(iss::POST_SYNC); /* call post-sync if needed */
|
||||||
this->gen_trap_check(this->leave_blk);
|
this->gen_trap_check(this->leave_blk);
|
||||||
return std::make_tuple(iss::vm::BRANCH, nullptr);
|
return std::make_tuple(iss::vm::BRANCH, nullptr);
|
||||||
|
|
|
@ -74,13 +74,15 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
using vm::vm_base<ARCH>::get_reg_ptr;
|
||||||
|
|
||||||
template <typename T> inline llvm::ConstantInt *size(T type) {
|
template <typename T> inline llvm::ConstantInt *size(T type) {
|
||||||
return llvm::ConstantInt::get(getContext(), llvm::APInt(32, type->getType()->getScalarSizeInBits()));
|
return llvm::ConstantInt::get(getContext(), llvm::APInt(32, type->getType()->getScalarSizeInBits()));
|
||||||
}
|
}
|
||||||
|
|
||||||
inline llvm::Value *gen_choose(llvm::Value *cond, llvm::Value *trueVal, llvm::Value *falseVal,
|
inline llvm::Value *gen_choose(llvm::Value *cond, llvm::Value *trueVal, llvm::Value *falseVal,
|
||||||
unsigned size) const {
|
unsigned size) const {
|
||||||
return this->gen_cond_assign(cond, this->gen_ext(trueVal, size), this->gen_ext(falseVal, size));
|
return super::gen_cond_assign(cond, this->gen_ext(trueVal, size), this->gen_ext(falseVal, size));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::tuple<vm::continuation_e, llvm::BasicBlock *> gen_single_inst_behavior(virt_addr_t &, unsigned int &,
|
std::tuple<vm::continuation_e, llvm::BasicBlock *> gen_single_inst_behavior(virt_addr_t &, unsigned int &,
|
||||||
|
@ -98,55 +100,17 @@ protected:
|
||||||
|
|
||||||
void gen_trap_check(llvm::BasicBlock *bb);
|
void gen_trap_check(llvm::BasicBlock *bb);
|
||||||
|
|
||||||
|
|
||||||
|
inline llvm::Value *gen_reg_load(unsigned i, unsigned level = 0) {
|
||||||
|
return this->builder->CreateLoad(get_reg_ptr(i), false);
|
||||||
|
}
|
||||||
|
|
||||||
inline void gen_set_pc(virt_addr_t pc, unsigned reg_num) {
|
inline void gen_set_pc(virt_addr_t pc, unsigned reg_num) {
|
||||||
llvm::Value *next_pc_v = this->builder->CreateSExtOrTrunc(this->gen_const(traits<ARCH>::XLEN, pc.val),
|
llvm::Value *next_pc_v = this->builder->CreateSExtOrTrunc(this->gen_const(traits<ARCH>::XLEN, pc.val),
|
||||||
this->get_type(traits<ARCH>::XLEN));
|
this->get_type(traits<ARCH>::XLEN));
|
||||||
this->builder->CreateStore(next_pc_v, get_reg_ptr(reg_num), true);
|
this->builder->CreateStore(next_pc_v, get_reg_ptr(reg_num), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline llvm::Value *get_reg_ptr(unsigned i) {
|
|
||||||
void *ptr = this->core.get_regs_base_ptr() + traits<ARCH>::reg_byte_offset(i);
|
|
||||||
llvm::PointerType *ptrType = nullptr;
|
|
||||||
switch (traits<ARCH>::reg_bit_width(i) >> 3) {
|
|
||||||
case 8:
|
|
||||||
ptrType = llvm::Type::getInt64PtrTy(this->mod->getContext());
|
|
||||||
break;
|
|
||||||
case 4:
|
|
||||||
ptrType = llvm::Type::getInt32PtrTy(this->mod->getContext());
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
ptrType = llvm::Type::getInt16PtrTy(this->mod->getContext());
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
ptrType = llvm::Type::getInt8PtrTy(this->mod->getContext());
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
throw std::runtime_error("unsupported access with");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return llvm::ConstantExpr::getIntToPtr(
|
|
||||||
llvm::ConstantInt::get(this->mod->getContext(),
|
|
||||||
llvm::APInt(8 /*bits*/ * sizeof(uint8_t *), reinterpret_cast<uint64_t>(ptr))),
|
|
||||||
ptrType);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline llvm::Value *gen_reg_load(unsigned i, unsigned level = 0) {
|
|
||||||
// if(level){
|
|
||||||
return this->builder->CreateLoad(get_reg_ptr(i), false);
|
|
||||||
// } else {
|
|
||||||
// if(!this->loaded_regs[i])
|
|
||||||
// this->loaded_regs[i]=this->builder->CreateLoad(get_reg_ptr(i),
|
|
||||||
// false);
|
|
||||||
// return this->loaded_regs[i];
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void gen_set_pc(virt_addr_t pc) {
|
|
||||||
llvm::Value *pc_l = this->builder->CreateSExt(this->gen_const(traits<ARCH>::caddr_bit_width, (unsigned)pc),
|
|
||||||
this->get_type(traits<ARCH>::caddr_bit_width));
|
|
||||||
super::gen_set_reg(traits<ARCH>::PC, pc_l);
|
|
||||||
}
|
|
||||||
|
|
||||||
// some compile time constants
|
// some compile time constants
|
||||||
// enum { MASK16 = 0b1111110001100011, MASK32 = 0b11111111111100000111000001111111 };
|
// enum { MASK16 = 0b1111110001100011, MASK32 = 0b11111111111100000111000001111111 };
|
||||||
enum { MASK16 = 0b1111111111111111, MASK32 = 0b11111111111100000111000001111111 };
|
enum { MASK16 = 0b1111111111111111, MASK32 = 0b11111111111100000111000001111111 };
|
||||||
|
|
Loading…
Reference in New Issue