updates templates and vm impls for better LAST_BRANCH handling

This commit is contained in:
2024-07-22 09:04:17 +02:00
parent 4f5d9214ed
commit 0432803d82
6 changed files with 103 additions and 54 deletions

View File

@ -440,6 +440,7 @@ private:
gen_instr_prologue(jh);
cc.comment("//behavior:");
/*generate behavior*/
mov(jh.cc, get_ptr_for(jh, traits::LAST_BRANCH), static_cast<int>(NO_JUMP));
if(rd>=static_cast<uint32_t>(traits::RFS)){
gen_raise(jh, 0, static_cast<int32_t>(traits::RV_CAUSE_ILLEGAL_INSTRUCTION));
}
@ -456,7 +457,7 @@ private:
}
auto PC_val_v = new_pc;
mov(cc, jh.next_pc, PC_val_v);
mov(cc, get_ptr_for(jh, traits::LAST_BRANCH), 32U);
mov(cc, get_ptr_for(jh, traits::LAST_BRANCH), static_cast<int>(KNOWN_JUMP));
}
}
auto returnValue = BRANCH;
@ -498,6 +499,7 @@ private:
gen_instr_prologue(jh);
cc.comment("//behavior:");
/*generate behavior*/
mov(jh.cc, get_ptr_for(jh, traits::LAST_BRANCH), static_cast<int>(NO_JUMP));
if(rd>=static_cast<uint32_t>(traits::RFS)||rs1>=static_cast<uint32_t>(traits::RFS)){
gen_raise(jh, 0, static_cast<int32_t>(traits::RV_CAUSE_ILLEGAL_INSTRUCTION));
}
@ -525,7 +527,7 @@ private:
}
auto PC_val_v = new_pc;
mov(cc, jh.next_pc, PC_val_v);
mov(cc, get_ptr_for(jh, traits::LAST_BRANCH), 32U);
mov(cc, get_ptr_for(jh, traits::LAST_BRANCH), static_cast<int>(UNKNOWN_JUMP));
}
cc.bind(label_merge);
}
@ -568,6 +570,7 @@ private:
gen_instr_prologue(jh);
cc.comment("//behavior:");
/*generate behavior*/
mov(jh.cc, get_ptr_for(jh, traits::LAST_BRANCH), static_cast<int>(NO_JUMP));
if(rs2>=static_cast<uint32_t>(traits::RFS)||rs1>=static_cast<uint32_t>(traits::RFS)){
gen_raise(jh, 0, static_cast<int32_t>(traits::RV_CAUSE_ILLEGAL_INSTRUCTION));
}
@ -585,7 +588,7 @@ private:
else{
auto PC_val_v = new_pc;
mov(cc, jh.next_pc, PC_val_v);
mov(cc, get_ptr_for(jh, traits::LAST_BRANCH), 32U);
mov(cc, get_ptr_for(jh, traits::LAST_BRANCH), static_cast<int>(KNOWN_JUMP));
}
}
cc.bind(label_merge);
@ -629,6 +632,7 @@ private:
gen_instr_prologue(jh);
cc.comment("//behavior:");
/*generate behavior*/
mov(jh.cc, get_ptr_for(jh, traits::LAST_BRANCH), static_cast<int>(NO_JUMP));
if(rs2>=static_cast<uint32_t>(traits::RFS)||rs1>=static_cast<uint32_t>(traits::RFS)){
gen_raise(jh, 0, static_cast<int32_t>(traits::RV_CAUSE_ILLEGAL_INSTRUCTION));
}
@ -646,7 +650,7 @@ private:
else{
auto PC_val_v = new_pc;
mov(cc, jh.next_pc, PC_val_v);
mov(cc, get_ptr_for(jh, traits::LAST_BRANCH), 32U);
mov(cc, get_ptr_for(jh, traits::LAST_BRANCH), static_cast<int>(KNOWN_JUMP));
}
}
cc.bind(label_merge);
@ -690,6 +694,7 @@ private:
gen_instr_prologue(jh);
cc.comment("//behavior:");
/*generate behavior*/
mov(jh.cc, get_ptr_for(jh, traits::LAST_BRANCH), static_cast<int>(NO_JUMP));
if(rs2>=static_cast<uint32_t>(traits::RFS)||rs1>=static_cast<uint32_t>(traits::RFS)){
gen_raise(jh, 0, static_cast<int32_t>(traits::RV_CAUSE_ILLEGAL_INSTRUCTION));
}
@ -709,7 +714,7 @@ private:
else{
auto PC_val_v = new_pc;
mov(cc, jh.next_pc, PC_val_v);
mov(cc, get_ptr_for(jh, traits::LAST_BRANCH), 32U);
mov(cc, get_ptr_for(jh, traits::LAST_BRANCH), static_cast<int>(KNOWN_JUMP));
}
}
cc.bind(label_merge);
@ -753,6 +758,7 @@ private:
gen_instr_prologue(jh);
cc.comment("//behavior:");
/*generate behavior*/
mov(jh.cc, get_ptr_for(jh, traits::LAST_BRANCH), static_cast<int>(NO_JUMP));
if(rs2>=static_cast<uint32_t>(traits::RFS)||rs1>=static_cast<uint32_t>(traits::RFS)){
gen_raise(jh, 0, static_cast<int32_t>(traits::RV_CAUSE_ILLEGAL_INSTRUCTION));
}
@ -772,7 +778,7 @@ private:
else{
auto PC_val_v = new_pc;
mov(cc, jh.next_pc, PC_val_v);
mov(cc, get_ptr_for(jh, traits::LAST_BRANCH), 32U);
mov(cc, get_ptr_for(jh, traits::LAST_BRANCH), static_cast<int>(KNOWN_JUMP));
}
}
cc.bind(label_merge);
@ -816,6 +822,7 @@ private:
gen_instr_prologue(jh);
cc.comment("//behavior:");
/*generate behavior*/
mov(jh.cc, get_ptr_for(jh, traits::LAST_BRANCH), static_cast<int>(NO_JUMP));
if(rs2>=static_cast<uint32_t>(traits::RFS)||rs1>=static_cast<uint32_t>(traits::RFS)){
gen_raise(jh, 0, static_cast<int32_t>(traits::RV_CAUSE_ILLEGAL_INSTRUCTION));
}
@ -833,7 +840,7 @@ private:
else{
auto PC_val_v = new_pc;
mov(cc, jh.next_pc, PC_val_v);
mov(cc, get_ptr_for(jh, traits::LAST_BRANCH), 32U);
mov(cc, get_ptr_for(jh, traits::LAST_BRANCH), static_cast<int>(KNOWN_JUMP));
}
}
cc.bind(label_merge);
@ -877,6 +884,7 @@ private:
gen_instr_prologue(jh);
cc.comment("//behavior:");
/*generate behavior*/
mov(jh.cc, get_ptr_for(jh, traits::LAST_BRANCH), static_cast<int>(NO_JUMP));
if(rs2>=static_cast<uint32_t>(traits::RFS)||rs1>=static_cast<uint32_t>(traits::RFS)){
gen_raise(jh, 0, static_cast<int32_t>(traits::RV_CAUSE_ILLEGAL_INSTRUCTION));
}
@ -894,7 +902,7 @@ private:
else{
auto PC_val_v = new_pc;
mov(cc, jh.next_pc, PC_val_v);
mov(cc, get_ptr_for(jh, traits::LAST_BRANCH), 32U);
mov(cc, get_ptr_for(jh, traits::LAST_BRANCH), static_cast<int>(KNOWN_JUMP));
}
}
cc.bind(label_merge);
@ -2387,6 +2395,7 @@ private:
gen_instr_prologue(jh);
cc.comment("//behavior:");
/*generate behavior*/
mov(jh.cc, get_ptr_for(jh, traits::LAST_BRANCH), static_cast<int>(NO_JUMP));
gen_raise(jh, 0, 11);
auto returnValue = TRAP;
@ -2423,6 +2432,7 @@ private:
gen_instr_prologue(jh);
cc.comment("//behavior:");
/*generate behavior*/
mov(jh.cc, get_ptr_for(jh, traits::LAST_BRANCH), static_cast<int>(NO_JUMP));
gen_raise(jh, 0, 3);
auto returnValue = TRAP;
@ -2459,6 +2469,7 @@ private:
gen_instr_prologue(jh);
cc.comment("//behavior:");
/*generate behavior*/
mov(jh.cc, get_ptr_for(jh, traits::LAST_BRANCH), static_cast<int>(NO_JUMP));
gen_leave(jh, 3);
auto returnValue = TRAP;
@ -3629,11 +3640,12 @@ private:
gen_instr_prologue(jh);
cc.comment("//behavior:");
/*generate behavior*/
mov(jh.cc, get_ptr_for(jh, traits::LAST_BRANCH), static_cast<int>(NO_JUMP));
mov(cc, get_ptr_for(jh, traits::X0+ 1),
(uint32_t)(PC+2));
auto PC_val_v = (uint32_t)(PC+(int16_t)sext<12>(imm));
mov(cc, jh.next_pc, PC_val_v);
mov(cc, get_ptr_for(jh, traits::LAST_BRANCH), 32U);
mov(cc, get_ptr_for(jh, traits::LAST_BRANCH), static_cast<int>(KNOWN_JUMP));
auto returnValue = BRANCH;
gen_sync(jh, POST_SYNC, 62);
@ -4148,9 +4160,10 @@ private:
gen_instr_prologue(jh);
cc.comment("//behavior:");
/*generate behavior*/
mov(jh.cc, get_ptr_for(jh, traits::LAST_BRANCH), static_cast<int>(NO_JUMP));
auto PC_val_v = (uint32_t)(PC+(int16_t)sext<12>(imm));
mov(cc, jh.next_pc, PC_val_v);
mov(cc, get_ptr_for(jh, traits::LAST_BRANCH), 32U);
mov(cc, get_ptr_for(jh, traits::LAST_BRANCH), static_cast<int>(KNOWN_JUMP));
auto returnValue = BRANCH;
gen_sync(jh, POST_SYNC, 74);
@ -4189,6 +4202,7 @@ private:
gen_instr_prologue(jh);
cc.comment("//behavior:");
/*generate behavior*/
mov(jh.cc, get_ptr_for(jh, traits::LAST_BRANCH), static_cast<int>(NO_JUMP));
auto label_merge = cc.newLabel();
cmp(cc, gen_operation(cc, eq, load_reg_from_mem(jh, traits::X0 + rs1+8), 0)
,0);
@ -4196,7 +4210,7 @@ private:
{
auto PC_val_v = (uint32_t)(PC+(int16_t)sext<9>(imm));
mov(cc, jh.next_pc, PC_val_v);
mov(cc, get_ptr_for(jh, traits::LAST_BRANCH), 32U);
mov(cc, get_ptr_for(jh, traits::LAST_BRANCH), static_cast<int>(KNOWN_JUMP));
}
cc.bind(label_merge);
auto returnValue = BRANCH;
@ -4237,6 +4251,7 @@ private:
gen_instr_prologue(jh);
cc.comment("//behavior:");
/*generate behavior*/
mov(jh.cc, get_ptr_for(jh, traits::LAST_BRANCH), static_cast<int>(NO_JUMP));
auto label_merge = cc.newLabel();
cmp(cc, gen_operation(cc, ne, load_reg_from_mem(jh, traits::X0 + rs1+8), 0)
,0);
@ -4244,7 +4259,7 @@ private:
{
auto PC_val_v = (uint32_t)(PC+(int16_t)sext<9>(imm));
mov(cc, jh.next_pc, PC_val_v);
mov(cc, get_ptr_for(jh, traits::LAST_BRANCH), 32U);
mov(cc, get_ptr_for(jh, traits::LAST_BRANCH), static_cast<int>(KNOWN_JUMP));
}
cc.bind(label_merge);
auto returnValue = BRANCH;
@ -4429,12 +4444,13 @@ private:
gen_instr_prologue(jh);
cc.comment("//behavior:");
/*generate behavior*/
mov(jh.cc, get_ptr_for(jh, traits::LAST_BRANCH), static_cast<int>(NO_JUMP));
if(rs1&&rs1<static_cast<uint32_t>(traits::RFS)){
auto addr_mask = (uint32_t)- 2;
auto PC_val_v = gen_operation(cc, band, load_reg_from_mem(jh, traits::X0 + rs1%static_cast<uint32_t>(traits::RFS)), addr_mask)
;
mov(cc, jh.next_pc, PC_val_v);
mov(cc, get_ptr_for(jh, traits::LAST_BRANCH), 32U);
mov(cc, get_ptr_for(jh, traits::LAST_BRANCH), static_cast<int>(UNKNOWN_JUMP));
}
else{
gen_raise(jh, 0, 2);
@ -4561,6 +4577,7 @@ private:
gen_instr_prologue(jh);
cc.comment("//behavior:");
/*generate behavior*/
mov(jh.cc, get_ptr_for(jh, traits::LAST_BRANCH), static_cast<int>(NO_JUMP));
if(rs1>=static_cast<uint32_t>(traits::RFS)){
gen_raise(jh, 0, static_cast<int32_t>(traits::RV_CAUSE_ILLEGAL_INSTRUCTION));
}
@ -4572,7 +4589,7 @@ private:
auto PC_val_v = gen_operation(cc, band, new_pc, addr_mask)
;
mov(cc, jh.next_pc, PC_val_v);
mov(cc, get_ptr_for(jh, traits::LAST_BRANCH), 32U);
mov(cc, get_ptr_for(jh, traits::LAST_BRANCH), static_cast<int>(UNKNOWN_JUMP));
}
auto returnValue = BRANCH;
@ -4870,7 +4887,7 @@ void vm_impl<ARCH>::gen_block_epilogue(jit_holder& jh){
mov(cc, current_next_pc, get_ptr_for(jh, traits::NEXT_PC));
mov(cc, jh.next_pc, current_next_pc);
mov(cc, get_ptr_for(jh, traits::LAST_BRANCH), std::numeric_limits<uint32_t>::max());
mov(cc, get_ptr_for(jh, traits::LAST_BRANCH), static_cast<int>(UNKNOWN_JUMP));
cc.ret(jh.next_pc);
}
template <typename ARCH>