Preparation for multi-threading/multi-core DBT

This commit is contained in:
Eyck Jentzsch 2017-12-07 22:37:43 +01:00
parent 3ea46d882b
commit b4871ac725
3 changed files with 43 additions and 104 deletions

@ -1 +1 @@
Subproject commit d0422e5f8df2391df372779b06c807d456a058a3 Subproject commit cf9679475121f85a6333970f80bb6a40a8b4a0a5

View File

@ -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);

View File

@ -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 };