updates templates and vm impls for better LAST_BRANCH handling
This commit is contained in:
@@ -449,6 +449,7 @@ private:
|
||||
|
||||
this->gen_instr_prologue();
|
||||
/*generate behavior*/
|
||||
this->builder.CreateStore(this->gen_const(32U, static_cast<int>(NO_JUMP)), get_reg_ptr(traits::LAST_BRANCH), false);
|
||||
if(rd>=static_cast<uint32_t>(traits::RFS)) {
|
||||
this->gen_raise_trap(0, static_cast<int32_t>(traits::RV_CAUSE_ILLEGAL_INSTRUCTION));
|
||||
}
|
||||
@@ -465,7 +466,7 @@ private:
|
||||
}
|
||||
auto PC_val_v = new_pc;
|
||||
this->builder.CreateStore(this->gen_const(32,PC_val_v), get_reg_ptr(traits::NEXT_PC), false);
|
||||
this->builder.CreateStore(this->gen_const(32,2U), get_reg_ptr(traits::LAST_BRANCH), false);
|
||||
this->builder.CreateStore(this->gen_const(32, static_cast<int>(KNOWN_JUMP)), get_reg_ptr(traits::LAST_BRANCH), false);
|
||||
}
|
||||
}
|
||||
bb = this->leave_blk;
|
||||
@@ -505,6 +506,7 @@ private:
|
||||
|
||||
this->gen_instr_prologue();
|
||||
/*generate behavior*/
|
||||
this->builder.CreateStore(this->gen_const(32U, static_cast<int>(NO_JUMP)), get_reg_ptr(traits::LAST_BRANCH), false);
|
||||
if(rd>=static_cast<uint32_t>(traits::RFS)||rs1>=static_cast<uint32_t>(traits::RFS)) {
|
||||
this->gen_raise_trap(0, static_cast<int32_t>(traits::RV_CAUSE_ILLEGAL_INSTRUCTION));
|
||||
}
|
||||
@@ -541,7 +543,7 @@ private:
|
||||
}
|
||||
auto PC_val_v = new_pc;
|
||||
this->builder.CreateStore(PC_val_v, get_reg_ptr(traits::NEXT_PC), false);
|
||||
this->builder.CreateStore(this->gen_const(32,2U), get_reg_ptr(traits::LAST_BRANCH), false);
|
||||
this->builder.CreateStore(this->gen_const(32, static_cast<int>(UNKNOWN_JUMP)), get_reg_ptr(traits::LAST_BRANCH), false);
|
||||
}
|
||||
this->builder.CreateBr(bb_merge);
|
||||
this->builder.SetInsertPoint(bb_merge);
|
||||
@@ -583,6 +585,7 @@ private:
|
||||
|
||||
this->gen_instr_prologue();
|
||||
/*generate behavior*/
|
||||
this->builder.CreateStore(this->gen_const(32U, static_cast<int>(NO_JUMP)), get_reg_ptr(traits::LAST_BRANCH), false);
|
||||
if(rs2>=static_cast<uint32_t>(traits::RFS)||rs1>=static_cast<uint32_t>(traits::RFS)) {
|
||||
this->gen_raise_trap(0, static_cast<int32_t>(traits::RV_CAUSE_ILLEGAL_INSTRUCTION));
|
||||
}
|
||||
@@ -602,7 +605,7 @@ private:
|
||||
else{
|
||||
auto PC_val_v = new_pc;
|
||||
this->builder.CreateStore(this->gen_const(32,PC_val_v), get_reg_ptr(traits::NEXT_PC), false);
|
||||
this->builder.CreateStore(this->gen_const(32,2U), get_reg_ptr(traits::LAST_BRANCH), false);
|
||||
this->builder.CreateStore(this->gen_const(32, static_cast<int>(KNOWN_JUMP)), get_reg_ptr(traits::LAST_BRANCH), false);
|
||||
}
|
||||
}
|
||||
this->builder.CreateBr(bb_merge);
|
||||
@@ -645,6 +648,7 @@ private:
|
||||
|
||||
this->gen_instr_prologue();
|
||||
/*generate behavior*/
|
||||
this->builder.CreateStore(this->gen_const(32U, static_cast<int>(NO_JUMP)), get_reg_ptr(traits::LAST_BRANCH), false);
|
||||
if(rs2>=static_cast<uint32_t>(traits::RFS)||rs1>=static_cast<uint32_t>(traits::RFS)) {
|
||||
this->gen_raise_trap(0, static_cast<int32_t>(traits::RV_CAUSE_ILLEGAL_INSTRUCTION));
|
||||
}
|
||||
@@ -664,7 +668,7 @@ private:
|
||||
else{
|
||||
auto PC_val_v = new_pc;
|
||||
this->builder.CreateStore(this->gen_const(32,PC_val_v), get_reg_ptr(traits::NEXT_PC), false);
|
||||
this->builder.CreateStore(this->gen_const(32,2U), get_reg_ptr(traits::LAST_BRANCH), false);
|
||||
this->builder.CreateStore(this->gen_const(32, static_cast<int>(KNOWN_JUMP)), get_reg_ptr(traits::LAST_BRANCH), false);
|
||||
}
|
||||
}
|
||||
this->builder.CreateBr(bb_merge);
|
||||
@@ -707,6 +711,7 @@ private:
|
||||
|
||||
this->gen_instr_prologue();
|
||||
/*generate behavior*/
|
||||
this->builder.CreateStore(this->gen_const(32U, static_cast<int>(NO_JUMP)), get_reg_ptr(traits::LAST_BRANCH), false);
|
||||
if(rs2>=static_cast<uint32_t>(traits::RFS)||rs1>=static_cast<uint32_t>(traits::RFS)) {
|
||||
this->gen_raise_trap(0, static_cast<int32_t>(traits::RV_CAUSE_ILLEGAL_INSTRUCTION));
|
||||
}
|
||||
@@ -730,7 +735,7 @@ private:
|
||||
else{
|
||||
auto PC_val_v = new_pc;
|
||||
this->builder.CreateStore(this->gen_const(32,PC_val_v), get_reg_ptr(traits::NEXT_PC), false);
|
||||
this->builder.CreateStore(this->gen_const(32,2U), get_reg_ptr(traits::LAST_BRANCH), false);
|
||||
this->builder.CreateStore(this->gen_const(32, static_cast<int>(KNOWN_JUMP)), get_reg_ptr(traits::LAST_BRANCH), false);
|
||||
}
|
||||
}
|
||||
this->builder.CreateBr(bb_merge);
|
||||
@@ -773,6 +778,7 @@ private:
|
||||
|
||||
this->gen_instr_prologue();
|
||||
/*generate behavior*/
|
||||
this->builder.CreateStore(this->gen_const(32U, static_cast<int>(NO_JUMP)), get_reg_ptr(traits::LAST_BRANCH), false);
|
||||
if(rs2>=static_cast<uint32_t>(traits::RFS)||rs1>=static_cast<uint32_t>(traits::RFS)) {
|
||||
this->gen_raise_trap(0, static_cast<int32_t>(traits::RV_CAUSE_ILLEGAL_INSTRUCTION));
|
||||
}
|
||||
@@ -796,7 +802,7 @@ private:
|
||||
else{
|
||||
auto PC_val_v = new_pc;
|
||||
this->builder.CreateStore(this->gen_const(32,PC_val_v), get_reg_ptr(traits::NEXT_PC), false);
|
||||
this->builder.CreateStore(this->gen_const(32,2U), get_reg_ptr(traits::LAST_BRANCH), false);
|
||||
this->builder.CreateStore(this->gen_const(32, static_cast<int>(KNOWN_JUMP)), get_reg_ptr(traits::LAST_BRANCH), false);
|
||||
}
|
||||
}
|
||||
this->builder.CreateBr(bb_merge);
|
||||
@@ -839,6 +845,7 @@ private:
|
||||
|
||||
this->gen_instr_prologue();
|
||||
/*generate behavior*/
|
||||
this->builder.CreateStore(this->gen_const(32U, static_cast<int>(NO_JUMP)), get_reg_ptr(traits::LAST_BRANCH), false);
|
||||
if(rs2>=static_cast<uint32_t>(traits::RFS)||rs1>=static_cast<uint32_t>(traits::RFS)) {
|
||||
this->gen_raise_trap(0, static_cast<int32_t>(traits::RV_CAUSE_ILLEGAL_INSTRUCTION));
|
||||
}
|
||||
@@ -858,7 +865,7 @@ private:
|
||||
else{
|
||||
auto PC_val_v = new_pc;
|
||||
this->builder.CreateStore(this->gen_const(32,PC_val_v), get_reg_ptr(traits::NEXT_PC), false);
|
||||
this->builder.CreateStore(this->gen_const(32,2U), get_reg_ptr(traits::LAST_BRANCH), false);
|
||||
this->builder.CreateStore(this->gen_const(32, static_cast<int>(KNOWN_JUMP)), get_reg_ptr(traits::LAST_BRANCH), false);
|
||||
}
|
||||
}
|
||||
this->builder.CreateBr(bb_merge);
|
||||
@@ -901,6 +908,7 @@ private:
|
||||
|
||||
this->gen_instr_prologue();
|
||||
/*generate behavior*/
|
||||
this->builder.CreateStore(this->gen_const(32U, static_cast<int>(NO_JUMP)), get_reg_ptr(traits::LAST_BRANCH), false);
|
||||
if(rs2>=static_cast<uint32_t>(traits::RFS)||rs1>=static_cast<uint32_t>(traits::RFS)) {
|
||||
this->gen_raise_trap(0, static_cast<int32_t>(traits::RV_CAUSE_ILLEGAL_INSTRUCTION));
|
||||
}
|
||||
@@ -920,7 +928,7 @@ private:
|
||||
else{
|
||||
auto PC_val_v = new_pc;
|
||||
this->builder.CreateStore(this->gen_const(32,PC_val_v), get_reg_ptr(traits::NEXT_PC), false);
|
||||
this->builder.CreateStore(this->gen_const(32,2U), get_reg_ptr(traits::LAST_BRANCH), false);
|
||||
this->builder.CreateStore(this->gen_const(32, static_cast<int>(KNOWN_JUMP)), get_reg_ptr(traits::LAST_BRANCH), false);
|
||||
}
|
||||
}
|
||||
this->builder.CreateBr(bb_merge);
|
||||
@@ -2431,6 +2439,7 @@ private:
|
||||
|
||||
this->gen_instr_prologue();
|
||||
/*generate behavior*/
|
||||
this->builder.CreateStore(this->gen_const(32U, static_cast<int>(NO_JUMP)), get_reg_ptr(traits::LAST_BRANCH), false);
|
||||
this->gen_raise_trap(0, 11);
|
||||
bb = this->leave_blk;
|
||||
auto returnValue = std::make_tuple(TRAP,nullptr);
|
||||
@@ -2465,6 +2474,7 @@ private:
|
||||
|
||||
this->gen_instr_prologue();
|
||||
/*generate behavior*/
|
||||
this->builder.CreateStore(this->gen_const(32U, static_cast<int>(NO_JUMP)), get_reg_ptr(traits::LAST_BRANCH), false);
|
||||
this->gen_raise_trap(0, 3);
|
||||
bb = this->leave_blk;
|
||||
auto returnValue = std::make_tuple(TRAP,nullptr);
|
||||
@@ -2499,6 +2509,7 @@ private:
|
||||
|
||||
this->gen_instr_prologue();
|
||||
/*generate behavior*/
|
||||
this->builder.CreateStore(this->gen_const(32U, static_cast<int>(NO_JUMP)), get_reg_ptr(traits::LAST_BRANCH), false);
|
||||
this->gen_leave_trap(3);
|
||||
bb = this->leave_blk;
|
||||
auto returnValue = std::make_tuple(TRAP,nullptr);
|
||||
@@ -3746,12 +3757,13 @@ private:
|
||||
|
||||
this->gen_instr_prologue();
|
||||
/*generate behavior*/
|
||||
this->builder.CreateStore(this->gen_const(32U, static_cast<int>(NO_JUMP)), get_reg_ptr(traits::LAST_BRANCH), false);
|
||||
this->builder.CreateStore(
|
||||
this->gen_const(32,(uint32_t)(PC+2)),
|
||||
get_reg_ptr(1 + traits::X0), false);
|
||||
auto PC_val_v = (uint32_t)(PC+(int16_t)sext<12>(imm));
|
||||
this->builder.CreateStore(this->gen_const(32,PC_val_v), get_reg_ptr(traits::NEXT_PC), false);
|
||||
this->builder.CreateStore(this->gen_const(32,2U), get_reg_ptr(traits::LAST_BRANCH), false);
|
||||
this->builder.CreateStore(this->gen_const(32, static_cast<int>(KNOWN_JUMP)), get_reg_ptr(traits::LAST_BRANCH), false);
|
||||
bb = this->leave_blk;
|
||||
auto returnValue = std::make_tuple(BRANCH,nullptr);
|
||||
|
||||
@@ -4276,9 +4288,10 @@ private:
|
||||
|
||||
this->gen_instr_prologue();
|
||||
/*generate behavior*/
|
||||
this->builder.CreateStore(this->gen_const(32U, static_cast<int>(NO_JUMP)), get_reg_ptr(traits::LAST_BRANCH), false);
|
||||
auto PC_val_v = (uint32_t)(PC+(int16_t)sext<12>(imm));
|
||||
this->builder.CreateStore(this->gen_const(32,PC_val_v), get_reg_ptr(traits::NEXT_PC), false);
|
||||
this->builder.CreateStore(this->gen_const(32,2U), get_reg_ptr(traits::LAST_BRANCH), false);
|
||||
this->builder.CreateStore(this->gen_const(32, static_cast<int>(KNOWN_JUMP)), get_reg_ptr(traits::LAST_BRANCH), false);
|
||||
bb = this->leave_blk;
|
||||
auto returnValue = std::make_tuple(BRANCH,nullptr);
|
||||
|
||||
@@ -4315,6 +4328,7 @@ private:
|
||||
|
||||
this->gen_instr_prologue();
|
||||
/*generate behavior*/
|
||||
this->builder.CreateStore(this->gen_const(32U, static_cast<int>(NO_JUMP)), get_reg_ptr(traits::LAST_BRANCH), false);
|
||||
auto bb_merge = BasicBlock::Create(this->mod->getContext(), "bb_merge", this->func, this->leave_blk);
|
||||
auto bb_then = BasicBlock::Create(this->mod->getContext(), "bb_then", this->func, bb_merge);
|
||||
this->builder.CreateCondBr(this->gen_bool(this->builder.CreateICmp(ICmpInst::ICMP_EQ,
|
||||
@@ -4325,7 +4339,7 @@ private:
|
||||
{
|
||||
auto PC_val_v = (uint32_t)(PC+(int16_t)sext<9>(imm));
|
||||
this->builder.CreateStore(this->gen_const(32,PC_val_v), get_reg_ptr(traits::NEXT_PC), false);
|
||||
this->builder.CreateStore(this->gen_const(32,2U), get_reg_ptr(traits::LAST_BRANCH), false);
|
||||
this->builder.CreateStore(this->gen_const(32, static_cast<int>(KNOWN_JUMP)), get_reg_ptr(traits::LAST_BRANCH), false);
|
||||
}
|
||||
this->builder.CreateBr(bb_merge);
|
||||
this->builder.SetInsertPoint(bb_merge);
|
||||
@@ -4365,6 +4379,7 @@ private:
|
||||
|
||||
this->gen_instr_prologue();
|
||||
/*generate behavior*/
|
||||
this->builder.CreateStore(this->gen_const(32U, static_cast<int>(NO_JUMP)), get_reg_ptr(traits::LAST_BRANCH), false);
|
||||
auto bb_merge = BasicBlock::Create(this->mod->getContext(), "bb_merge", this->func, this->leave_blk);
|
||||
auto bb_then = BasicBlock::Create(this->mod->getContext(), "bb_then", this->func, bb_merge);
|
||||
this->builder.CreateCondBr(this->gen_bool(this->builder.CreateICmp(ICmpInst::ICMP_NE,
|
||||
@@ -4375,7 +4390,7 @@ private:
|
||||
{
|
||||
auto PC_val_v = (uint32_t)(PC+(int16_t)sext<9>(imm));
|
||||
this->builder.CreateStore(this->gen_const(32,PC_val_v), get_reg_ptr(traits::NEXT_PC), false);
|
||||
this->builder.CreateStore(this->gen_const(32,2U), get_reg_ptr(traits::LAST_BRANCH), false);
|
||||
this->builder.CreateStore(this->gen_const(32, static_cast<int>(KNOWN_JUMP)), get_reg_ptr(traits::LAST_BRANCH), false);
|
||||
}
|
||||
this->builder.CreateBr(bb_merge);
|
||||
this->builder.SetInsertPoint(bb_merge);
|
||||
@@ -4563,13 +4578,14 @@ private:
|
||||
|
||||
this->gen_instr_prologue();
|
||||
/*generate behavior*/
|
||||
this->builder.CreateStore(this->gen_const(32U, static_cast<int>(NO_JUMP)), get_reg_ptr(traits::LAST_BRANCH), false);
|
||||
if(rs1&&rs1<static_cast<uint32_t>(traits::RFS)){ auto addr_mask =(uint32_t)- 2;
|
||||
auto PC_val_v = this->builder.CreateAnd(
|
||||
this->gen_reg_load(rs1%static_cast<uint32_t>(traits::RFS)+ traits::X0, 0),
|
||||
this->gen_const(32,addr_mask))
|
||||
;
|
||||
this->builder.CreateStore(PC_val_v, get_reg_ptr(traits::NEXT_PC), false);
|
||||
this->builder.CreateStore(this->gen_const(32,2U), get_reg_ptr(traits::LAST_BRANCH), false);
|
||||
this->builder.CreateStore(this->gen_const(32, static_cast<int>(UNKNOWN_JUMP)), get_reg_ptr(traits::LAST_BRANCH), false);
|
||||
}
|
||||
else{
|
||||
this->gen_raise_trap(0, 2);
|
||||
@@ -4694,6 +4710,7 @@ private:
|
||||
|
||||
this->gen_instr_prologue();
|
||||
/*generate behavior*/
|
||||
this->builder.CreateStore(this->gen_const(32U, static_cast<int>(NO_JUMP)), get_reg_ptr(traits::LAST_BRANCH), false);
|
||||
if(rs1>=static_cast<uint32_t>(traits::RFS)) {
|
||||
this->gen_raise_trap(0, static_cast<int32_t>(traits::RV_CAUSE_ILLEGAL_INSTRUCTION));
|
||||
}
|
||||
@@ -4708,7 +4725,7 @@ private:
|
||||
this->gen_const(32,addr_mask))
|
||||
;
|
||||
this->builder.CreateStore(PC_val_v, get_reg_ptr(traits::NEXT_PC), false);
|
||||
this->builder.CreateStore(this->gen_const(32,2U), get_reg_ptr(traits::LAST_BRANCH), false);
|
||||
this->builder.CreateStore(this->gen_const(32, static_cast<int>(UNKNOWN_JUMP)), get_reg_ptr(traits::LAST_BRANCH), false);
|
||||
}
|
||||
bb = this->leave_blk;
|
||||
auto returnValue = std::make_tuple(BRANCH,nullptr);
|
||||
@@ -4987,7 +5004,7 @@ template <typename ARCH>
|
||||
void vm_impl<ARCH>::gen_leave_trap(unsigned lvl) {
|
||||
std::vector<Value *> args{ this->core_ptr, ConstantInt::get(getContext(), APInt(64, lvl)) };
|
||||
this->builder.CreateCall(this->mod->getFunction("leave_trap"), args);
|
||||
this->builder.CreateStore(this->gen_const(32U, std::numeric_limits<uint32_t>::max()), get_reg_ptr(traits::LAST_BRANCH), false);
|
||||
this->builder.CreateStore(this->gen_const(32U, static_cast<int>(UNKNOWN_JUMP)), get_reg_ptr(traits::LAST_BRANCH), false);
|
||||
}
|
||||
|
||||
template <typename ARCH>
|
||||
@@ -5015,7 +5032,7 @@ void vm_impl<ARCH>::gen_trap_behavior(BasicBlock *trap_blk) {
|
||||
this->adj_to64(cur_pc_val),
|
||||
this->adj_to64(this->builder.CreateLoad(this->get_type(64),this->tval))};
|
||||
this->builder.CreateCall(this->mod->getFunction("enter_trap"), args);
|
||||
this->builder.CreateStore(this->gen_const(32U, std::numeric_limits<uint32_t>::max()), get_reg_ptr(traits::LAST_BRANCH), false);
|
||||
this->builder.CreateStore(this->gen_const(32U, static_cast<int>(UNKNOWN_JUMP)), get_reg_ptr(traits::LAST_BRANCH), false);
|
||||
|
||||
auto *trap_addr_val = this->builder.CreateLoad(this->get_typeptr(traits::NEXT_PC), get_reg_ptr(traits::NEXT_PC), false);
|
||||
this->builder.CreateRet(trap_addr_val);
|
||||
|
Reference in New Issue
Block a user