integrates new tval changes into llvm

This commit is contained in:
Eyck-Alexander Jentzsch 2024-07-17 14:17:02 +02:00
parent 7a199e122d
commit ac1a26a10c
2 changed files with 152 additions and 27 deletions

View File

@ -102,6 +102,8 @@ protected:
void gen_raise_trap(uint16_t trap_id, uint16_t cause);
void gen_leave_trap(unsigned lvl);
void gen_wait(unsigned type);
void set_tval(uint64_t new_tval);
void set_tval(Value* new_tval);
void gen_trap_behavior(BasicBlock *) override;
void gen_instr_epilogue(BasicBlock *bb);
@ -168,6 +170,7 @@ private:
auto cur_pc_val = this->gen_const(32,pc.val);
pc=pc+ ${instr.length/8};
this->gen_set_pc(pc, traits::NEXT_PC);
this->set_tval(PC);
/*generate behavior*/
<%instr.behavior.eachLine{%>${it}
@ -326,6 +329,15 @@ void vm_impl<ARCH>::gen_wait(unsigned type) {
this->builder.CreateCall(this->mod->getFunction("wait"), args);
}
template <typename ARCH>
inline void vm_impl<ARCH>::set_tval(uint64_t tval) {
auto tmp_tval = this->gen_const(64, tval);
this->set_tval(tmp_tval);
}
template <typename ARCH>
inline void vm_impl<ARCH>::set_tval(Value* new_tval) {
this->builder.CreateStore(new_tval, this->tval);
}
template <typename ARCH>
void vm_impl<ARCH>::gen_trap_behavior(BasicBlock *trap_blk) {
this->builder.SetInsertPoint(trap_blk);
@ -334,7 +346,7 @@ void vm_impl<ARCH>::gen_trap_behavior(BasicBlock *trap_blk) {
this->builder.CreateStore(this->gen_const(32U, std::numeric_limits<uint32_t>::max()),
get_reg_ptr(traits::LAST_BRANCH), false);
std::vector<Value *> args{this->core_ptr, this->adj_to64(trap_state_val),
this->adj_to64(this->builder.CreateLoad(this->get_typeptr(traits::PC), get_reg_ptr(traits::PC), false))};
this->adj_to64(this->builder.CreateLoad(this->builder.getInt64Ty(),this->tval))};
this->builder.CreateCall(this->mod->getFunction("enter_trap"), args);
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);

View File

@ -102,6 +102,8 @@ protected:
void gen_raise_trap(uint16_t trap_id, uint16_t cause);
void gen_leave_trap(unsigned lvl);
void gen_wait(unsigned type);
void set_tval(uint64_t new_tval);
void set_tval(Value* new_tval);
void gen_trap_behavior(BasicBlock *) override;
void gen_instr_epilogue(BasicBlock *bb);
@ -349,6 +351,7 @@ private:
auto cur_pc_val = this->gen_const(32,pc.val);
pc=pc+ 4;
this->gen_set_pc(pc, traits::NEXT_PC);
this->set_tval(PC);
/*generate behavior*/
if(rd>=static_cast<uint32_t>(traits::RFS)) {
@ -392,6 +395,7 @@ private:
auto cur_pc_val = this->gen_const(32,pc.val);
pc=pc+ 4;
this->gen_set_pc(pc, traits::NEXT_PC);
this->set_tval(PC);
/*generate behavior*/
if(rd>=static_cast<uint32_t>(traits::RFS)) {
@ -435,13 +439,16 @@ private:
auto cur_pc_val = this->gen_const(32,pc.val);
pc=pc+ 4;
this->gen_set_pc(pc, traits::NEXT_PC);
this->set_tval(PC);
/*generate behavior*/
if(rd>=static_cast<uint32_t>(traits::RFS)) {
this->gen_raise_trap(0, static_cast<int32_t>(traits::RV_CAUSE_ILLEGAL_INSTRUCTION));
}
else{
if(imm%static_cast<uint32_t>(traits::INSTR_ALIGNMENT)){ this->gen_raise_trap(0, 0);
auto new_pc =(uint32_t)(PC+(int32_t)sext<21>(imm));
if(new_pc%static_cast<uint32_t>(traits::INSTR_ALIGNMENT)){ this->set_tval(new_pc);
this->gen_raise_trap(0, 0);
}
else{
if(rd!=0) {
@ -449,7 +456,7 @@ private:
this->gen_const(32,(uint32_t)(PC+4)),
get_reg_ptr(rd + traits::X0), false);
}
auto PC_val_v = (uint32_t)(PC+(int32_t)sext<21>(imm));
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);
}
@ -486,20 +493,21 @@ private:
auto cur_pc_val = this->gen_const(32,pc.val);
pc=pc+ 4;
this->gen_set_pc(pc, traits::NEXT_PC);
this->set_tval(PC);
/*generate behavior*/
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));
}
else{
auto addr_mask =this->gen_const(32,(uint32_t)- 2);
auto addr_mask =(uint32_t)- 2;
auto new_pc =this->gen_ext(
(this->builder.CreateAnd(
(this->builder.CreateAdd(
this->gen_ext(this->gen_reg_load(rs1+ traits::X0, 0), 64,false),
this->gen_ext(this->gen_const(16,(int16_t)sext<12>(imm)), 64,true))
),
this->gen_ext(addr_mask, 64,false))
this->gen_ext(this->gen_const(32,addr_mask), 64,false))
),
32, true);
auto bb_merge = BasicBlock::Create(this->mod->getContext(), "bb_merge", this->func, this->leave_blk);
@ -511,6 +519,7 @@ private:
, 1), bb_then, bb_else);
this->builder.SetInsertPoint(bb_then);
{
this->set_tval(new_pc);
this->gen_raise_trap(0, 0);
}
this->builder.CreateBr(bb_merge);
@ -560,6 +569,7 @@ private:
auto cur_pc_val = this->gen_const(32,pc.val);
pc=pc+ 4;
this->gen_set_pc(pc, traits::NEXT_PC);
this->set_tval(PC);
/*generate behavior*/
if(rs2>=static_cast<uint32_t>(traits::RFS)||rs1>=static_cast<uint32_t>(traits::RFS)) {
@ -574,10 +584,12 @@ private:
, 1), bb_then, bb_merge);
this->builder.SetInsertPoint(bb_then);
{
if(imm%static_cast<uint32_t>(traits::INSTR_ALIGNMENT)){ this->gen_raise_trap(0, 0);
auto new_pc =(uint32_t)(PC+(int16_t)sext<13>(imm));
if(new_pc%static_cast<uint32_t>(traits::INSTR_ALIGNMENT)){ this->set_tval(new_pc);
this->gen_raise_trap(0, 0);
}
else{
auto PC_val_v = (uint32_t)(PC+(int16_t)sext<13>(imm));
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);
}
@ -617,6 +629,7 @@ private:
auto cur_pc_val = this->gen_const(32,pc.val);
pc=pc+ 4;
this->gen_set_pc(pc, traits::NEXT_PC);
this->set_tval(PC);
/*generate behavior*/
if(rs2>=static_cast<uint32_t>(traits::RFS)||rs1>=static_cast<uint32_t>(traits::RFS)) {
@ -631,10 +644,12 @@ private:
, 1), bb_then, bb_merge);
this->builder.SetInsertPoint(bb_then);
{
if(imm%static_cast<uint32_t>(traits::INSTR_ALIGNMENT)){ this->gen_raise_trap(0, 0);
auto new_pc =(uint32_t)(PC+(int16_t)sext<13>(imm));
if(new_pc%static_cast<uint32_t>(traits::INSTR_ALIGNMENT)){ this->set_tval(new_pc);
this->gen_raise_trap(0, 0);
}
else{
auto PC_val_v = (uint32_t)(PC+(int16_t)sext<13>(imm));
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);
}
@ -674,6 +689,7 @@ private:
auto cur_pc_val = this->gen_const(32,pc.val);
pc=pc+ 4;
this->gen_set_pc(pc, traits::NEXT_PC);
this->set_tval(PC);
/*generate behavior*/
if(rs2>=static_cast<uint32_t>(traits::RFS)||rs1>=static_cast<uint32_t>(traits::RFS)) {
@ -692,10 +708,12 @@ private:
, 1), bb_then, bb_merge);
this->builder.SetInsertPoint(bb_then);
{
if(imm%static_cast<uint32_t>(traits::INSTR_ALIGNMENT)){ this->gen_raise_trap(0, 0);
auto new_pc =(uint32_t)(PC+(int16_t)sext<13>(imm));
if(new_pc%static_cast<uint32_t>(traits::INSTR_ALIGNMENT)){ this->set_tval(new_pc);
this->gen_raise_trap(0, 0);
}
else{
auto PC_val_v = (uint32_t)(PC+(int16_t)sext<13>(imm));
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);
}
@ -735,6 +753,7 @@ private:
auto cur_pc_val = this->gen_const(32,pc.val);
pc=pc+ 4;
this->gen_set_pc(pc, traits::NEXT_PC);
this->set_tval(PC);
/*generate behavior*/
if(rs2>=static_cast<uint32_t>(traits::RFS)||rs1>=static_cast<uint32_t>(traits::RFS)) {
@ -753,10 +772,12 @@ private:
, 1), bb_then, bb_merge);
this->builder.SetInsertPoint(bb_then);
{
if(imm%static_cast<uint32_t>(traits::INSTR_ALIGNMENT)){ this->gen_raise_trap(0, 0);
auto new_pc =(uint32_t)(PC+(int16_t)sext<13>(imm));
if(new_pc%static_cast<uint32_t>(traits::INSTR_ALIGNMENT)){ this->set_tval(new_pc);
this->gen_raise_trap(0, 0);
}
else{
auto PC_val_v = (uint32_t)(PC+(int16_t)sext<13>(imm));
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);
}
@ -796,6 +817,7 @@ private:
auto cur_pc_val = this->gen_const(32,pc.val);
pc=pc+ 4;
this->gen_set_pc(pc, traits::NEXT_PC);
this->set_tval(PC);
/*generate behavior*/
if(rs2>=static_cast<uint32_t>(traits::RFS)||rs1>=static_cast<uint32_t>(traits::RFS)) {
@ -810,10 +832,12 @@ private:
, 1), bb_then, bb_merge);
this->builder.SetInsertPoint(bb_then);
{
if(imm%static_cast<uint32_t>(traits::INSTR_ALIGNMENT)){ this->gen_raise_trap(0, 0);
auto new_pc =(uint32_t)(PC+(int16_t)sext<13>(imm));
if(new_pc%static_cast<uint32_t>(traits::INSTR_ALIGNMENT)){ this->set_tval(new_pc);
this->gen_raise_trap(0, 0);
}
else{
auto PC_val_v = (uint32_t)(PC+(int16_t)sext<13>(imm));
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);
}
@ -853,6 +877,7 @@ private:
auto cur_pc_val = this->gen_const(32,pc.val);
pc=pc+ 4;
this->gen_set_pc(pc, traits::NEXT_PC);
this->set_tval(PC);
/*generate behavior*/
if(rs2>=static_cast<uint32_t>(traits::RFS)||rs1>=static_cast<uint32_t>(traits::RFS)) {
@ -867,10 +892,12 @@ private:
, 1), bb_then, bb_merge);
this->builder.SetInsertPoint(bb_then);
{
if(imm%static_cast<uint32_t>(traits::INSTR_ALIGNMENT)){ this->gen_raise_trap(0, 0);
auto new_pc =(uint32_t)(PC+(int16_t)sext<13>(imm));
if(new_pc%static_cast<uint32_t>(traits::INSTR_ALIGNMENT)){ this->set_tval(new_pc);
this->gen_raise_trap(0, 0);
}
else{
auto PC_val_v = (uint32_t)(PC+(int16_t)sext<13>(imm));
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);
}
@ -910,6 +937,7 @@ private:
auto cur_pc_val = this->gen_const(32,pc.val);
pc=pc+ 4;
this->gen_set_pc(pc, traits::NEXT_PC);
this->set_tval(PC);
/*generate behavior*/
if(rd>=static_cast<uint32_t>(traits::RFS)||rs1>=static_cast<uint32_t>(traits::RFS)) {
@ -965,6 +993,7 @@ private:
auto cur_pc_val = this->gen_const(32,pc.val);
pc=pc+ 4;
this->gen_set_pc(pc, traits::NEXT_PC);
this->set_tval(PC);
/*generate behavior*/
if(rd>=static_cast<uint32_t>(traits::RFS)||rs1>=static_cast<uint32_t>(traits::RFS)) {
@ -1020,6 +1049,7 @@ private:
auto cur_pc_val = this->gen_const(32,pc.val);
pc=pc+ 4;
this->gen_set_pc(pc, traits::NEXT_PC);
this->set_tval(PC);
/*generate behavior*/
if(rd>=static_cast<uint32_t>(traits::RFS)||rs1>=static_cast<uint32_t>(traits::RFS)) {
@ -1075,6 +1105,7 @@ private:
auto cur_pc_val = this->gen_const(32,pc.val);
pc=pc+ 4;
this->gen_set_pc(pc, traits::NEXT_PC);
this->set_tval(PC);
/*generate behavior*/
if(rd>=static_cast<uint32_t>(traits::RFS)||rs1>=static_cast<uint32_t>(traits::RFS)) {
@ -1128,6 +1159,7 @@ private:
auto cur_pc_val = this->gen_const(32,pc.val);
pc=pc+ 4;
this->gen_set_pc(pc, traits::NEXT_PC);
this->set_tval(PC);
/*generate behavior*/
if(rd>=static_cast<uint32_t>(traits::RFS)||rs1>=static_cast<uint32_t>(traits::RFS)) {
@ -1181,6 +1213,7 @@ private:
auto cur_pc_val = this->gen_const(32,pc.val);
pc=pc+ 4;
this->gen_set_pc(pc, traits::NEXT_PC);
this->set_tval(PC);
/*generate behavior*/
if(rs2>=static_cast<uint32_t>(traits::RFS)||rs1>=static_cast<uint32_t>(traits::RFS)) {
@ -1231,6 +1264,7 @@ private:
auto cur_pc_val = this->gen_const(32,pc.val);
pc=pc+ 4;
this->gen_set_pc(pc, traits::NEXT_PC);
this->set_tval(PC);
/*generate behavior*/
if(rs2>=static_cast<uint32_t>(traits::RFS)||rs1>=static_cast<uint32_t>(traits::RFS)) {
@ -1281,6 +1315,7 @@ private:
auto cur_pc_val = this->gen_const(32,pc.val);
pc=pc+ 4;
this->gen_set_pc(pc, traits::NEXT_PC);
this->set_tval(PC);
/*generate behavior*/
if(rs2>=static_cast<uint32_t>(traits::RFS)||rs1>=static_cast<uint32_t>(traits::RFS)) {
@ -1331,6 +1366,7 @@ private:
auto cur_pc_val = this->gen_const(32,pc.val);
pc=pc+ 4;
this->gen_set_pc(pc, traits::NEXT_PC);
this->set_tval(PC);
/*generate behavior*/
if(rd>=static_cast<uint32_t>(traits::RFS)||rs1>=static_cast<uint32_t>(traits::RFS)) {
@ -1380,6 +1416,7 @@ private:
auto cur_pc_val = this->gen_const(32,pc.val);
pc=pc+ 4;
this->gen_set_pc(pc, traits::NEXT_PC);
this->set_tval(PC);
/*generate behavior*/
if(rd>=static_cast<uint32_t>(traits::RFS)||rs1>=static_cast<uint32_t>(traits::RFS)) {
@ -1431,6 +1468,7 @@ private:
auto cur_pc_val = this->gen_const(32,pc.val);
pc=pc+ 4;
this->gen_set_pc(pc, traits::NEXT_PC);
this->set_tval(PC);
/*generate behavior*/
if(rd>=static_cast<uint32_t>(traits::RFS)||rs1>=static_cast<uint32_t>(traits::RFS)) {
@ -1481,6 +1519,7 @@ private:
auto cur_pc_val = this->gen_const(32,pc.val);
pc=pc+ 4;
this->gen_set_pc(pc, traits::NEXT_PC);
this->set_tval(PC);
/*generate behavior*/
if(rd>=static_cast<uint32_t>(traits::RFS)||rs1>=static_cast<uint32_t>(traits::RFS)) {
@ -1528,6 +1567,7 @@ private:
auto cur_pc_val = this->gen_const(32,pc.val);
pc=pc+ 4;
this->gen_set_pc(pc, traits::NEXT_PC);
this->set_tval(PC);
/*generate behavior*/
if(rd>=static_cast<uint32_t>(traits::RFS)||rs1>=static_cast<uint32_t>(traits::RFS)) {
@ -1575,6 +1615,7 @@ private:
auto cur_pc_val = this->gen_const(32,pc.val);
pc=pc+ 4;
this->gen_set_pc(pc, traits::NEXT_PC);
this->set_tval(PC);
/*generate behavior*/
if(rd>=static_cast<uint32_t>(traits::RFS)||rs1>=static_cast<uint32_t>(traits::RFS)) {
@ -1622,6 +1663,7 @@ private:
auto cur_pc_val = this->gen_const(32,pc.val);
pc=pc+ 4;
this->gen_set_pc(pc, traits::NEXT_PC);
this->set_tval(PC);
/*generate behavior*/
if(rd>=static_cast<uint32_t>(traits::RFS)||rs1>=static_cast<uint32_t>(traits::RFS)) {
@ -1669,6 +1711,7 @@ private:
auto cur_pc_val = this->gen_const(32,pc.val);
pc=pc+ 4;
this->gen_set_pc(pc, traits::NEXT_PC);
this->set_tval(PC);
/*generate behavior*/
if(rd>=static_cast<uint32_t>(traits::RFS)||rs1>=static_cast<uint32_t>(traits::RFS)) {
@ -1716,6 +1759,7 @@ private:
auto cur_pc_val = this->gen_const(32,pc.val);
pc=pc+ 4;
this->gen_set_pc(pc, traits::NEXT_PC);
this->set_tval(PC);
/*generate behavior*/
if(rd>=static_cast<uint32_t>(traits::RFS)||rs1>=static_cast<uint32_t>(traits::RFS)) {
@ -1765,6 +1809,7 @@ private:
auto cur_pc_val = this->gen_const(32,pc.val);
pc=pc+ 4;
this->gen_set_pc(pc, traits::NEXT_PC);
this->set_tval(PC);
/*generate behavior*/
if(rd>=static_cast<uint32_t>(traits::RFS)||rs1>=static_cast<uint32_t>(traits::RFS)||rs2>=static_cast<uint32_t>(traits::RFS)) {
@ -1814,6 +1859,7 @@ private:
auto cur_pc_val = this->gen_const(32,pc.val);
pc=pc+ 4;
this->gen_set_pc(pc, traits::NEXT_PC);
this->set_tval(PC);
/*generate behavior*/
if(rd>=static_cast<uint32_t>(traits::RFS)||rs1>=static_cast<uint32_t>(traits::RFS)||rs2>=static_cast<uint32_t>(traits::RFS)) {
@ -1863,6 +1909,7 @@ private:
auto cur_pc_val = this->gen_const(32,pc.val);
pc=pc+ 4;
this->gen_set_pc(pc, traits::NEXT_PC);
this->set_tval(PC);
/*generate behavior*/
if(rd>=static_cast<uint32_t>(traits::RFS)||rs1>=static_cast<uint32_t>(traits::RFS)||rs2>=static_cast<uint32_t>(traits::RFS)) {
@ -1913,6 +1960,7 @@ private:
auto cur_pc_val = this->gen_const(32,pc.val);
pc=pc+ 4;
this->gen_set_pc(pc, traits::NEXT_PC);
this->set_tval(PC);
/*generate behavior*/
if(rd>=static_cast<uint32_t>(traits::RFS)||rs1>=static_cast<uint32_t>(traits::RFS)||rs2>=static_cast<uint32_t>(traits::RFS)) {
@ -1965,6 +2013,7 @@ private:
auto cur_pc_val = this->gen_const(32,pc.val);
pc=pc+ 4;
this->gen_set_pc(pc, traits::NEXT_PC);
this->set_tval(PC);
/*generate behavior*/
if(rd>=static_cast<uint32_t>(traits::RFS)||rs1>=static_cast<uint32_t>(traits::RFS)||rs2>=static_cast<uint32_t>(traits::RFS)) {
@ -2015,6 +2064,7 @@ private:
auto cur_pc_val = this->gen_const(32,pc.val);
pc=pc+ 4;
this->gen_set_pc(pc, traits::NEXT_PC);
this->set_tval(PC);
/*generate behavior*/
if(rd>=static_cast<uint32_t>(traits::RFS)||rs1>=static_cast<uint32_t>(traits::RFS)||rs2>=static_cast<uint32_t>(traits::RFS)) {
@ -2062,6 +2112,7 @@ private:
auto cur_pc_val = this->gen_const(32,pc.val);
pc=pc+ 4;
this->gen_set_pc(pc, traits::NEXT_PC);
this->set_tval(PC);
/*generate behavior*/
if(rd>=static_cast<uint32_t>(traits::RFS)||rs1>=static_cast<uint32_t>(traits::RFS)||rs2>=static_cast<uint32_t>(traits::RFS)) {
@ -2112,6 +2163,7 @@ private:
auto cur_pc_val = this->gen_const(32,pc.val);
pc=pc+ 4;
this->gen_set_pc(pc, traits::NEXT_PC);
this->set_tval(PC);
/*generate behavior*/
if(rd>=static_cast<uint32_t>(traits::RFS)||rs1>=static_cast<uint32_t>(traits::RFS)||rs2>=static_cast<uint32_t>(traits::RFS)) {
@ -2165,6 +2217,7 @@ private:
auto cur_pc_val = this->gen_const(32,pc.val);
pc=pc+ 4;
this->gen_set_pc(pc, traits::NEXT_PC);
this->set_tval(PC);
/*generate behavior*/
if(rd>=static_cast<uint32_t>(traits::RFS)||rs1>=static_cast<uint32_t>(traits::RFS)||rs2>=static_cast<uint32_t>(traits::RFS)) {
@ -2212,6 +2265,7 @@ private:
auto cur_pc_val = this->gen_const(32,pc.val);
pc=pc+ 4;
this->gen_set_pc(pc, traits::NEXT_PC);
this->set_tval(PC);
/*generate behavior*/
if(rd>=static_cast<uint32_t>(traits::RFS)||rs1>=static_cast<uint32_t>(traits::RFS)||rs2>=static_cast<uint32_t>(traits::RFS)) {
@ -2261,6 +2315,7 @@ private:
auto cur_pc_val = this->gen_const(32,pc.val);
pc=pc+ 4;
this->gen_set_pc(pc, traits::NEXT_PC);
this->set_tval(PC);
/*generate behavior*/
this->gen_write_mem(traits::FENCE,
@ -2287,6 +2342,7 @@ private:
auto cur_pc_val = this->gen_const(32,pc.val);
pc=pc+ 4;
this->gen_set_pc(pc, traits::NEXT_PC);
this->set_tval(PC);
/*generate behavior*/
this->gen_raise_trap(0, 11);
@ -2311,6 +2367,7 @@ private:
auto cur_pc_val = this->gen_const(32,pc.val);
pc=pc+ 4;
this->gen_set_pc(pc, traits::NEXT_PC);
this->set_tval(PC);
/*generate behavior*/
this->gen_raise_trap(0, 3);
@ -2335,6 +2392,7 @@ private:
auto cur_pc_val = this->gen_const(32,pc.val);
pc=pc+ 4;
this->gen_set_pc(pc, traits::NEXT_PC);
this->set_tval(PC);
/*generate behavior*/
this->gen_leave_trap(3);
@ -2359,6 +2417,7 @@ private:
auto cur_pc_val = this->gen_const(32,pc.val);
pc=pc+ 4;
this->gen_set_pc(pc, traits::NEXT_PC);
this->set_tval(PC);
/*generate behavior*/
this->gen_wait(1);
@ -2394,6 +2453,7 @@ private:
auto cur_pc_val = this->gen_const(32,pc.val);
pc=pc+ 4;
this->gen_set_pc(pc, traits::NEXT_PC);
this->set_tval(PC);
/*generate behavior*/
if(rd>=static_cast<uint32_t>(traits::RFS)||rs1>=static_cast<uint32_t>(traits::RFS)) {
@ -2447,6 +2507,7 @@ private:
auto cur_pc_val = this->gen_const(32,pc.val);
pc=pc+ 4;
this->gen_set_pc(pc, traits::NEXT_PC);
this->set_tval(PC);
/*generate behavior*/
if(rd>=static_cast<uint32_t>(traits::RFS)||rs1>=static_cast<uint32_t>(traits::RFS)) {
@ -2501,6 +2562,7 @@ private:
auto cur_pc_val = this->gen_const(32,pc.val);
pc=pc+ 4;
this->gen_set_pc(pc, traits::NEXT_PC);
this->set_tval(PC);
/*generate behavior*/
if(rd>=static_cast<uint32_t>(traits::RFS)||rs1>=static_cast<uint32_t>(traits::RFS)) {
@ -2555,6 +2617,7 @@ private:
auto cur_pc_val = this->gen_const(32,pc.val);
pc=pc+ 4;
this->gen_set_pc(pc, traits::NEXT_PC);
this->set_tval(PC);
/*generate behavior*/
if(rd>=static_cast<uint32_t>(traits::RFS)) {
@ -2603,6 +2666,7 @@ private:
auto cur_pc_val = this->gen_const(32,pc.val);
pc=pc+ 4;
this->gen_set_pc(pc, traits::NEXT_PC);
this->set_tval(PC);
/*generate behavior*/
if(rd>=static_cast<uint32_t>(traits::RFS)) {
@ -2656,6 +2720,7 @@ private:
auto cur_pc_val = this->gen_const(32,pc.val);
pc=pc+ 4;
this->gen_set_pc(pc, traits::NEXT_PC);
this->set_tval(PC);
/*generate behavior*/
if(rd>=static_cast<uint32_t>(traits::RFS)) {
@ -2709,6 +2774,7 @@ private:
auto cur_pc_val = this->gen_const(32,pc.val);
pc=pc+ 4;
this->gen_set_pc(pc, traits::NEXT_PC);
this->set_tval(PC);
/*generate behavior*/
this->gen_write_mem(traits::FENCE,
@ -2746,6 +2812,7 @@ private:
auto cur_pc_val = this->gen_const(32,pc.val);
pc=pc+ 4;
this->gen_set_pc(pc, traits::NEXT_PC);
this->set_tval(PC);
/*generate behavior*/
if(rd>=static_cast<uint32_t>(traits::RFS)||rs1>=static_cast<uint32_t>(traits::RFS)||rs2>=static_cast<uint32_t>(traits::RFS)) {
@ -2798,6 +2865,7 @@ private:
auto cur_pc_val = this->gen_const(32,pc.val);
pc=pc+ 4;
this->gen_set_pc(pc, traits::NEXT_PC);
this->set_tval(PC);
/*generate behavior*/
if(rd>=static_cast<uint32_t>(traits::RFS)||rs1>=static_cast<uint32_t>(traits::RFS)||rs2>=static_cast<uint32_t>(traits::RFS)) {
@ -2853,6 +2921,7 @@ private:
auto cur_pc_val = this->gen_const(32,pc.val);
pc=pc+ 4;
this->gen_set_pc(pc, traits::NEXT_PC);
this->set_tval(PC);
/*generate behavior*/
if(rd>=static_cast<uint32_t>(traits::RFS)||rs1>=static_cast<uint32_t>(traits::RFS)||rs2>=static_cast<uint32_t>(traits::RFS)) {
@ -2907,6 +2976,7 @@ private:
auto cur_pc_val = this->gen_const(32,pc.val);
pc=pc+ 4;
this->gen_set_pc(pc, traits::NEXT_PC);
this->set_tval(PC);
/*generate behavior*/
if(rd>=static_cast<uint32_t>(traits::RFS)||rs1>=static_cast<uint32_t>(traits::RFS)||rs2>=static_cast<uint32_t>(traits::RFS)) {
@ -2960,6 +3030,7 @@ private:
auto cur_pc_val = this->gen_const(32,pc.val);
pc=pc+ 4;
this->gen_set_pc(pc, traits::NEXT_PC);
this->set_tval(PC);
/*generate behavior*/
if(rd>=static_cast<uint32_t>(traits::RFS)||rs1>=static_cast<uint32_t>(traits::RFS)||rs2>=static_cast<uint32_t>(traits::RFS)) {
@ -2979,14 +3050,14 @@ private:
, 1), bb_then, bb_else);
this->builder.SetInsertPoint(bb_then);
{
auto MMIN =this->gen_const(32,((uint32_t)1)<<(static_cast<uint32_t>(traits::XLEN)-1));
auto MMIN =((uint32_t)1)<<(static_cast<uint32_t>(traits::XLEN)-1);
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);
auto bb_else = BasicBlock::Create(this->mod->getContext(), "bb_else", this->func, bb_merge);
this->builder.CreateCondBr(this->gen_ext(this->builder.CreateAnd(
this->builder.CreateICmp(ICmpInst::ICMP_EQ,
this->gen_reg_load(rs1+ traits::X0, 0),
MMIN)
this->gen_const(32,MMIN))
,
this->builder.CreateICmp(ICmpInst::ICMP_EQ,
divisor,
@ -2996,7 +3067,7 @@ private:
this->builder.SetInsertPoint(bb_then);
{
this->builder.CreateStore(
MMIN,
this->gen_const(32,MMIN),
get_reg_ptr(rd + traits::X0), false);
}
this->builder.CreateBr(bb_merge);
@ -3057,6 +3128,7 @@ private:
auto cur_pc_val = this->gen_const(32,pc.val);
pc=pc+ 4;
this->gen_set_pc(pc, traits::NEXT_PC);
this->set_tval(PC);
/*generate behavior*/
if(rd>=static_cast<uint32_t>(traits::RFS)||rs1>=static_cast<uint32_t>(traits::RFS)||rs2>=static_cast<uint32_t>(traits::RFS)) {
@ -3125,6 +3197,7 @@ private:
auto cur_pc_val = this->gen_const(32,pc.val);
pc=pc+ 4;
this->gen_set_pc(pc, traits::NEXT_PC);
this->set_tval(PC);
/*generate behavior*/
if(rd>=static_cast<uint32_t>(traits::RFS)||rs1>=static_cast<uint32_t>(traits::RFS)||rs2>=static_cast<uint32_t>(traits::RFS)) {
@ -3140,14 +3213,14 @@ private:
, 1), bb_then, bb_else);
this->builder.SetInsertPoint(bb_then);
{
auto MMIN =this->gen_const(32,(uint32_t)1<<(static_cast<uint32_t>(traits::XLEN)-1));
auto MMIN =(uint32_t)1<<(static_cast<uint32_t>(traits::XLEN)-1);
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);
auto bb_else = BasicBlock::Create(this->mod->getContext(), "bb_else", this->func, bb_merge);
this->builder.CreateCondBr(this->gen_ext(this->builder.CreateAnd(
this->builder.CreateICmp(ICmpInst::ICMP_EQ,
this->gen_reg_load(rs1+ traits::X0, 0),
MMIN)
this->gen_const(32,MMIN))
,
this->builder.CreateICmp(ICmpInst::ICMP_EQ,
this->gen_ext(
@ -3226,6 +3299,7 @@ private:
auto cur_pc_val = this->gen_const(32,pc.val);
pc=pc+ 4;
this->gen_set_pc(pc, traits::NEXT_PC);
this->set_tval(PC);
/*generate behavior*/
if(rd>=static_cast<uint32_t>(traits::RFS)||rs1>=static_cast<uint32_t>(traits::RFS)||rs2>=static_cast<uint32_t>(traits::RFS)) {
@ -3293,6 +3367,7 @@ private:
auto cur_pc_val = this->gen_const(32,pc.val);
pc=pc+ 2;
this->gen_set_pc(pc, traits::NEXT_PC);
this->set_tval(PC);
/*generate behavior*/
if(imm) {
@ -3340,6 +3415,7 @@ private:
auto cur_pc_val = this->gen_const(32,pc.val);
pc=pc+ 2;
this->gen_set_pc(pc, traits::NEXT_PC);
this->set_tval(PC);
/*generate behavior*/
auto offs =this->gen_ext(
@ -3387,6 +3463,7 @@ private:
auto cur_pc_val = this->gen_const(32,pc.val);
pc=pc+ 2;
this->gen_set_pc(pc, traits::NEXT_PC);
this->set_tval(PC);
/*generate behavior*/
auto offs =this->gen_ext(
@ -3431,6 +3508,7 @@ private:
auto cur_pc_val = this->gen_const(32,pc.val);
pc=pc+ 2;
this->gen_set_pc(pc, traits::NEXT_PC);
this->set_tval(PC);
/*generate behavior*/
if(rs1>=static_cast<uint32_t>(traits::RFS)) {
@ -3470,6 +3548,7 @@ private:
auto cur_pc_val = this->gen_const(32,pc.val);
pc=pc+ 2;
this->gen_set_pc(pc, traits::NEXT_PC);
this->set_tval(PC);
/*generate behavior*/
bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk);
@ -3502,6 +3581,7 @@ private:
auto cur_pc_val = this->gen_const(32,pc.val);
pc=pc+ 2;
this->gen_set_pc(pc, traits::NEXT_PC);
this->set_tval(PC);
/*generate behavior*/
this->builder.CreateStore(
@ -3541,6 +3621,7 @@ private:
auto cur_pc_val = this->gen_const(32,pc.val);
pc=pc+ 2;
this->gen_set_pc(pc, traits::NEXT_PC);
this->set_tval(PC);
/*generate behavior*/
if(rd>=static_cast<uint32_t>(traits::RFS)) {
@ -3584,6 +3665,7 @@ private:
auto cur_pc_val = this->gen_const(32,pc.val);
pc=pc+ 2;
this->gen_set_pc(pc, traits::NEXT_PC);
this->set_tval(PC);
/*generate behavior*/
if(imm==0||rd>=static_cast<uint32_t>(traits::RFS)) {
@ -3624,6 +3706,7 @@ private:
auto cur_pc_val = this->gen_const(32,pc.val);
pc=pc+ 2;
this->gen_set_pc(pc, traits::NEXT_PC);
this->set_tval(PC);
/*generate behavior*/
if(nzimm) {
@ -3661,6 +3744,7 @@ private:
auto cur_pc_val = this->gen_const(32,pc.val);
pc=pc+ 2;
this->gen_set_pc(pc, traits::NEXT_PC);
this->set_tval(PC);
/*generate behavior*/
this->gen_raise_trap(0, static_cast<int32_t>(traits::RV_CAUSE_ILLEGAL_INSTRUCTION));
@ -3695,6 +3779,7 @@ private:
auto cur_pc_val = this->gen_const(32,pc.val);
pc=pc+ 2;
this->gen_set_pc(pc, traits::NEXT_PC);
this->set_tval(PC);
/*generate behavior*/
this->builder.CreateStore(
@ -3734,6 +3819,7 @@ private:
auto cur_pc_val = this->gen_const(32,pc.val);
pc=pc+ 2;
this->gen_set_pc(pc, traits::NEXT_PC);
this->set_tval(PC);
/*generate behavior*/
if(shamt){ this->builder.CreateStore(
@ -3791,6 +3877,7 @@ private:
auto cur_pc_val = this->gen_const(32,pc.val);
pc=pc+ 2;
this->gen_set_pc(pc, traits::NEXT_PC);
this->set_tval(PC);
/*generate behavior*/
this->builder.CreateStore(
@ -3832,6 +3919,7 @@ private:
auto cur_pc_val = this->gen_const(32,pc.val);
pc=pc+ 2;
this->gen_set_pc(pc, traits::NEXT_PC);
this->set_tval(PC);
/*generate behavior*/
this->builder.CreateStore(
@ -3873,6 +3961,7 @@ private:
auto cur_pc_val = this->gen_const(32,pc.val);
pc=pc+ 2;
this->gen_set_pc(pc, traits::NEXT_PC);
this->set_tval(PC);
/*generate behavior*/
this->builder.CreateStore(
@ -3912,6 +4001,7 @@ private:
auto cur_pc_val = this->gen_const(32,pc.val);
pc=pc+ 2;
this->gen_set_pc(pc, traits::NEXT_PC);
this->set_tval(PC);
/*generate behavior*/
this->builder.CreateStore(
@ -3951,6 +4041,7 @@ private:
auto cur_pc_val = this->gen_const(32,pc.val);
pc=pc+ 2;
this->gen_set_pc(pc, traits::NEXT_PC);
this->set_tval(PC);
/*generate behavior*/
this->builder.CreateStore(
@ -3989,6 +4080,7 @@ private:
auto cur_pc_val = this->gen_const(32,pc.val);
pc=pc+ 2;
this->gen_set_pc(pc, traits::NEXT_PC);
this->set_tval(PC);
/*generate behavior*/
auto PC_val_v = (uint32_t)(PC+(int16_t)sext<12>(imm));
@ -4025,6 +4117,7 @@ private:
auto cur_pc_val = this->gen_const(32,pc.val);
pc=pc+ 2;
this->gen_set_pc(pc, traits::NEXT_PC);
this->set_tval(PC);
/*generate behavior*/
auto bb_merge = BasicBlock::Create(this->mod->getContext(), "bb_merge", this->func, this->leave_blk);
@ -4072,6 +4165,7 @@ private:
auto cur_pc_val = this->gen_const(32,pc.val);
pc=pc+ 2;
this->gen_set_pc(pc, traits::NEXT_PC);
this->set_tval(PC);
/*generate behavior*/
auto bb_merge = BasicBlock::Create(this->mod->getContext(), "bb_merge", this->func, this->leave_blk);
@ -4119,6 +4213,7 @@ private:
auto cur_pc_val = this->gen_const(32,pc.val);
pc=pc+ 2;
this->gen_set_pc(pc, traits::NEXT_PC);
this->set_tval(PC);
/*generate behavior*/
if(rs1>=static_cast<uint32_t>(traits::RFS)) {
@ -4165,6 +4260,7 @@ private:
auto cur_pc_val = this->gen_const(32,pc.val);
pc=pc+ 2;
this->gen_set_pc(pc, traits::NEXT_PC);
this->set_tval(PC);
/*generate behavior*/
if(rd>=static_cast<uint32_t>(traits::RFS)||rd==0) {
@ -4216,6 +4312,7 @@ private:
auto cur_pc_val = this->gen_const(32,pc.val);
pc=pc+ 2;
this->gen_set_pc(pc, traits::NEXT_PC);
this->set_tval(PC);
/*generate behavior*/
if(rd>=static_cast<uint32_t>(traits::RFS)) {
@ -4258,12 +4355,13 @@ private:
auto cur_pc_val = this->gen_const(32,pc.val);
pc=pc+ 2;
this->gen_set_pc(pc, traits::NEXT_PC);
this->set_tval(PC);
/*generate behavior*/
if(rs1&&rs1<static_cast<uint32_t>(traits::RFS)){ auto addr_mask =this->gen_const(32,(uint32_t)- 2);
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),
addr_mask)
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);
@ -4292,6 +4390,7 @@ private:
auto cur_pc_val = this->gen_const(32,pc.val);
pc=pc+ 2;
this->gen_set_pc(pc, traits::NEXT_PC);
this->set_tval(PC);
/*generate behavior*/
this->gen_raise_trap(0, 2);
@ -4326,6 +4425,7 @@ private:
auto cur_pc_val = this->gen_const(32,pc.val);
pc=pc+ 2;
this->gen_set_pc(pc, traits::NEXT_PC);
this->set_tval(PC);
/*generate behavior*/
if(rd>=static_cast<uint32_t>(traits::RFS)) {
@ -4373,20 +4473,21 @@ private:
auto cur_pc_val = this->gen_const(32,pc.val);
pc=pc+ 2;
this->gen_set_pc(pc, traits::NEXT_PC);
this->set_tval(PC);
/*generate behavior*/
if(rs1>=static_cast<uint32_t>(traits::RFS)) {
this->gen_raise_trap(0, static_cast<int32_t>(traits::RV_CAUSE_ILLEGAL_INSTRUCTION));
}
else{
auto addr_mask =this->gen_const(32,(uint32_t)- 2);
auto addr_mask =(uint32_t)- 2;
auto new_pc =this->gen_reg_load(rs1+ traits::X0, 0);
this->builder.CreateStore(
this->gen_const(32,(uint32_t)(PC+2)),
get_reg_ptr(1 + traits::X0), false);
auto PC_val_v = this->builder.CreateAnd(
new_pc,
addr_mask)
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);
@ -4412,6 +4513,7 @@ private:
auto cur_pc_val = this->gen_const(32,pc.val);
pc=pc+ 2;
this->gen_set_pc(pc, traits::NEXT_PC);
this->set_tval(PC);
/*generate behavior*/
this->gen_raise_trap(0, 3);
@ -4446,6 +4548,7 @@ private:
auto cur_pc_val = this->gen_const(32,pc.val);
pc=pc+ 2;
this->gen_set_pc(pc, traits::NEXT_PC);
this->set_tval(PC);
/*generate behavior*/
if(rs2>=static_cast<uint32_t>(traits::RFS)) {
@ -4485,6 +4588,7 @@ private:
auto cur_pc_val = this->gen_const(32,pc.val);
pc=pc+ 2;
this->gen_set_pc(pc, traits::NEXT_PC);
this->set_tval(PC);
/*generate behavior*/
this->gen_raise_trap(0, static_cast<int32_t>(traits::RV_CAUSE_ILLEGAL_INSTRUCTION));
@ -4645,6 +4749,15 @@ void vm_impl<ARCH>::gen_wait(unsigned type) {
this->builder.CreateCall(this->mod->getFunction("wait"), args);
}
template <typename ARCH>
inline void vm_impl<ARCH>::set_tval(uint64_t tval) {
auto tmp_tval = this->gen_const(64, tval);
this->set_tval(tmp_tval);
}
template <typename ARCH>
inline void vm_impl<ARCH>::set_tval(Value* new_tval) {
this->builder.CreateStore(this->gen_ext(new_tval, 64, false), this->tval);
}
template <typename ARCH>
void vm_impl<ARCH>::gen_trap_behavior(BasicBlock *trap_blk) {
this->builder.SetInsertPoint(trap_blk);
@ -4653,7 +4766,7 @@ void vm_impl<ARCH>::gen_trap_behavior(BasicBlock *trap_blk) {
this->builder.CreateStore(this->gen_const(32U, std::numeric_limits<uint32_t>::max()),
get_reg_ptr(traits::LAST_BRANCH), false);
std::vector<Value *> args{this->core_ptr, this->adj_to64(trap_state_val),
this->adj_to64(this->builder.CreateLoad(this->get_typeptr(traits::PC), get_reg_ptr(traits::PC), false))};
this->adj_to64(this->builder.CreateLoad(this->get_type(64),this->tval))};
this->builder.CreateCall(this->mod->getFunction("enter_trap"), args);
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);