updates templates and vm impls for better LAST_BRANCH handling
This commit is contained in:
parent
4f5d9214ed
commit
0432803d82
|
@ -347,7 +347,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, current_next_pc, get_ptr_for(jh, traits::NEXT_PC));
|
||||||
mov(cc, jh.next_pc, current_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);
|
cc.ret(jh.next_pc);
|
||||||
}
|
}
|
||||||
template <typename ARCH>
|
template <typename ARCH>
|
||||||
|
|
|
@ -338,7 +338,7 @@ template <typename ARCH>
|
||||||
void vm_impl<ARCH>::gen_leave_trap(unsigned lvl) {
|
void vm_impl<ARCH>::gen_leave_trap(unsigned lvl) {
|
||||||
std::vector<Value *> args{ this->core_ptr, ConstantInt::get(getContext(), APInt(64, 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.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>
|
template <typename ARCH>
|
||||||
|
@ -366,7 +366,7 @@ void vm_impl<ARCH>::gen_trap_behavior(BasicBlock *trap_blk) {
|
||||||
this->adj_to64(cur_pc_val),
|
this->adj_to64(cur_pc_val),
|
||||||
this->adj_to64(this->builder.CreateLoad(this->get_type(64),this->tval))};
|
this->adj_to64(this->builder.CreateLoad(this->get_type(64),this->tval))};
|
||||||
this->builder.CreateCall(this->mod->getFunction("enter_trap"), args);
|
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);
|
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);
|
this->builder.CreateRet(trap_addr_val);
|
||||||
|
|
|
@ -302,13 +302,12 @@ vm_impl<ARCH>::gen_single_inst_behavior(virt_addr_t &pc, unsigned int &inst_cnt,
|
||||||
|
|
||||||
template <typename ARCH> void vm_impl<ARCH>::gen_raise_trap(tu_builder& tu, uint16_t trap_id, uint16_t cause) {
|
template <typename ARCH> void vm_impl<ARCH>::gen_raise_trap(tu_builder& tu, uint16_t trap_id, uint16_t cause) {
|
||||||
tu(" *trap_state = {:#x};", 0x80 << 24 | (cause << 16) | trap_id);
|
tu(" *trap_state = {:#x};", 0x80 << 24 | (cause << 16) | trap_id);
|
||||||
tu.store(traits::NEXT_PC, tu.constant(std::numeric_limits<uint32_t>::max(), 32));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename ARCH> void vm_impl<ARCH>::gen_leave_trap(tu_builder& tu, unsigned lvl) {
|
template <typename ARCH> void vm_impl<ARCH>::gen_leave_trap(tu_builder& tu, unsigned lvl) {
|
||||||
tu("leave_trap(core_ptr, {});", lvl);
|
tu("leave_trap(core_ptr, {});", lvl);
|
||||||
tu.store(traits::NEXT_PC, tu.read_mem(traits::CSR, (lvl << 8) + 0x41, traits::XLEN));
|
tu.store(traits::NEXT_PC, tu.read_mem(traits::CSR, (lvl << 8) + 0x41, traits::XLEN));
|
||||||
tu.store(traits::LAST_BRANCH, tu.constant(std::numeric_limits<uint32_t>::max(), 32));
|
tu.store(traits::LAST_BRANCH, tu.constant(static_cast<int>(UNKNOWN_JUMP), 32));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename ARCH> void vm_impl<ARCH>::gen_wait(tu_builder& tu, unsigned type) {
|
template <typename ARCH> void vm_impl<ARCH>::gen_wait(tu_builder& tu, unsigned type) {
|
||||||
|
@ -325,7 +324,7 @@ template <typename ARCH> void vm_impl<ARCH>::gen_trap_behavior(tu_builder& tu) {
|
||||||
tu("trap_entry:");
|
tu("trap_entry:");
|
||||||
this->gen_sync(tu, POST_SYNC, -1);
|
this->gen_sync(tu, POST_SYNC, -1);
|
||||||
tu("enter_trap(core_ptr, *trap_state, *pc, tval);");
|
tu("enter_trap(core_ptr, *trap_state, *pc, tval);");
|
||||||
tu.store(traits::LAST_BRANCH, tu.constant(std::numeric_limits<uint32_t>::max(),32));
|
tu.store(traits::LAST_BRANCH, tu.constant(static_cast<int>(UNKNOWN_JUMP),32));
|
||||||
tu("return *next_pc;");
|
tu("return *next_pc;");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -440,6 +440,7 @@ private:
|
||||||
gen_instr_prologue(jh);
|
gen_instr_prologue(jh);
|
||||||
cc.comment("//behavior:");
|
cc.comment("//behavior:");
|
||||||
/*generate 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)){
|
if(rd>=static_cast<uint32_t>(traits::RFS)){
|
||||||
gen_raise(jh, 0, static_cast<int32_t>(traits::RV_CAUSE_ILLEGAL_INSTRUCTION));
|
gen_raise(jh, 0, static_cast<int32_t>(traits::RV_CAUSE_ILLEGAL_INSTRUCTION));
|
||||||
}
|
}
|
||||||
|
@ -456,7 +457,7 @@ private:
|
||||||
}
|
}
|
||||||
auto PC_val_v = new_pc;
|
auto PC_val_v = new_pc;
|
||||||
mov(cc, jh.next_pc, PC_val_v);
|
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;
|
auto returnValue = BRANCH;
|
||||||
|
@ -498,6 +499,7 @@ private:
|
||||||
gen_instr_prologue(jh);
|
gen_instr_prologue(jh);
|
||||||
cc.comment("//behavior:");
|
cc.comment("//behavior:");
|
||||||
/*generate 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)){
|
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));
|
gen_raise(jh, 0, static_cast<int32_t>(traits::RV_CAUSE_ILLEGAL_INSTRUCTION));
|
||||||
}
|
}
|
||||||
|
@ -525,7 +527,7 @@ private:
|
||||||
}
|
}
|
||||||
auto PC_val_v = new_pc;
|
auto PC_val_v = new_pc;
|
||||||
mov(cc, jh.next_pc, PC_val_v);
|
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);
|
cc.bind(label_merge);
|
||||||
}
|
}
|
||||||
|
@ -568,6 +570,7 @@ private:
|
||||||
gen_instr_prologue(jh);
|
gen_instr_prologue(jh);
|
||||||
cc.comment("//behavior:");
|
cc.comment("//behavior:");
|
||||||
/*generate 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)){
|
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));
|
gen_raise(jh, 0, static_cast<int32_t>(traits::RV_CAUSE_ILLEGAL_INSTRUCTION));
|
||||||
}
|
}
|
||||||
|
@ -585,7 +588,7 @@ private:
|
||||||
else{
|
else{
|
||||||
auto PC_val_v = new_pc;
|
auto PC_val_v = new_pc;
|
||||||
mov(cc, jh.next_pc, PC_val_v);
|
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);
|
cc.bind(label_merge);
|
||||||
|
@ -629,6 +632,7 @@ private:
|
||||||
gen_instr_prologue(jh);
|
gen_instr_prologue(jh);
|
||||||
cc.comment("//behavior:");
|
cc.comment("//behavior:");
|
||||||
/*generate 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)){
|
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));
|
gen_raise(jh, 0, static_cast<int32_t>(traits::RV_CAUSE_ILLEGAL_INSTRUCTION));
|
||||||
}
|
}
|
||||||
|
@ -646,7 +650,7 @@ private:
|
||||||
else{
|
else{
|
||||||
auto PC_val_v = new_pc;
|
auto PC_val_v = new_pc;
|
||||||
mov(cc, jh.next_pc, PC_val_v);
|
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);
|
cc.bind(label_merge);
|
||||||
|
@ -690,6 +694,7 @@ private:
|
||||||
gen_instr_prologue(jh);
|
gen_instr_prologue(jh);
|
||||||
cc.comment("//behavior:");
|
cc.comment("//behavior:");
|
||||||
/*generate 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)){
|
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));
|
gen_raise(jh, 0, static_cast<int32_t>(traits::RV_CAUSE_ILLEGAL_INSTRUCTION));
|
||||||
}
|
}
|
||||||
|
@ -709,7 +714,7 @@ private:
|
||||||
else{
|
else{
|
||||||
auto PC_val_v = new_pc;
|
auto PC_val_v = new_pc;
|
||||||
mov(cc, jh.next_pc, PC_val_v);
|
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);
|
cc.bind(label_merge);
|
||||||
|
@ -753,6 +758,7 @@ private:
|
||||||
gen_instr_prologue(jh);
|
gen_instr_prologue(jh);
|
||||||
cc.comment("//behavior:");
|
cc.comment("//behavior:");
|
||||||
/*generate 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)){
|
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));
|
gen_raise(jh, 0, static_cast<int32_t>(traits::RV_CAUSE_ILLEGAL_INSTRUCTION));
|
||||||
}
|
}
|
||||||
|
@ -772,7 +778,7 @@ private:
|
||||||
else{
|
else{
|
||||||
auto PC_val_v = new_pc;
|
auto PC_val_v = new_pc;
|
||||||
mov(cc, jh.next_pc, PC_val_v);
|
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);
|
cc.bind(label_merge);
|
||||||
|
@ -816,6 +822,7 @@ private:
|
||||||
gen_instr_prologue(jh);
|
gen_instr_prologue(jh);
|
||||||
cc.comment("//behavior:");
|
cc.comment("//behavior:");
|
||||||
/*generate 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)){
|
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));
|
gen_raise(jh, 0, static_cast<int32_t>(traits::RV_CAUSE_ILLEGAL_INSTRUCTION));
|
||||||
}
|
}
|
||||||
|
@ -833,7 +840,7 @@ private:
|
||||||
else{
|
else{
|
||||||
auto PC_val_v = new_pc;
|
auto PC_val_v = new_pc;
|
||||||
mov(cc, jh.next_pc, PC_val_v);
|
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);
|
cc.bind(label_merge);
|
||||||
|
@ -877,6 +884,7 @@ private:
|
||||||
gen_instr_prologue(jh);
|
gen_instr_prologue(jh);
|
||||||
cc.comment("//behavior:");
|
cc.comment("//behavior:");
|
||||||
/*generate 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)){
|
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));
|
gen_raise(jh, 0, static_cast<int32_t>(traits::RV_CAUSE_ILLEGAL_INSTRUCTION));
|
||||||
}
|
}
|
||||||
|
@ -894,7 +902,7 @@ private:
|
||||||
else{
|
else{
|
||||||
auto PC_val_v = new_pc;
|
auto PC_val_v = new_pc;
|
||||||
mov(cc, jh.next_pc, PC_val_v);
|
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);
|
cc.bind(label_merge);
|
||||||
|
@ -2387,6 +2395,7 @@ private:
|
||||||
gen_instr_prologue(jh);
|
gen_instr_prologue(jh);
|
||||||
cc.comment("//behavior:");
|
cc.comment("//behavior:");
|
||||||
/*generate behavior*/
|
/*generate behavior*/
|
||||||
|
mov(jh.cc, get_ptr_for(jh, traits::LAST_BRANCH), static_cast<int>(NO_JUMP));
|
||||||
gen_raise(jh, 0, 11);
|
gen_raise(jh, 0, 11);
|
||||||
auto returnValue = TRAP;
|
auto returnValue = TRAP;
|
||||||
|
|
||||||
|
@ -2423,6 +2432,7 @@ private:
|
||||||
gen_instr_prologue(jh);
|
gen_instr_prologue(jh);
|
||||||
cc.comment("//behavior:");
|
cc.comment("//behavior:");
|
||||||
/*generate behavior*/
|
/*generate behavior*/
|
||||||
|
mov(jh.cc, get_ptr_for(jh, traits::LAST_BRANCH), static_cast<int>(NO_JUMP));
|
||||||
gen_raise(jh, 0, 3);
|
gen_raise(jh, 0, 3);
|
||||||
auto returnValue = TRAP;
|
auto returnValue = TRAP;
|
||||||
|
|
||||||
|
@ -2459,6 +2469,7 @@ private:
|
||||||
gen_instr_prologue(jh);
|
gen_instr_prologue(jh);
|
||||||
cc.comment("//behavior:");
|
cc.comment("//behavior:");
|
||||||
/*generate behavior*/
|
/*generate behavior*/
|
||||||
|
mov(jh.cc, get_ptr_for(jh, traits::LAST_BRANCH), static_cast<int>(NO_JUMP));
|
||||||
gen_leave(jh, 3);
|
gen_leave(jh, 3);
|
||||||
auto returnValue = TRAP;
|
auto returnValue = TRAP;
|
||||||
|
|
||||||
|
@ -3629,11 +3640,12 @@ private:
|
||||||
gen_instr_prologue(jh);
|
gen_instr_prologue(jh);
|
||||||
cc.comment("//behavior:");
|
cc.comment("//behavior:");
|
||||||
/*generate 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),
|
mov(cc, get_ptr_for(jh, traits::X0+ 1),
|
||||||
(uint32_t)(PC+2));
|
(uint32_t)(PC+2));
|
||||||
auto PC_val_v = (uint32_t)(PC+(int16_t)sext<12>(imm));
|
auto PC_val_v = (uint32_t)(PC+(int16_t)sext<12>(imm));
|
||||||
mov(cc, jh.next_pc, PC_val_v);
|
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;
|
auto returnValue = BRANCH;
|
||||||
|
|
||||||
gen_sync(jh, POST_SYNC, 62);
|
gen_sync(jh, POST_SYNC, 62);
|
||||||
|
@ -4148,9 +4160,10 @@ private:
|
||||||
gen_instr_prologue(jh);
|
gen_instr_prologue(jh);
|
||||||
cc.comment("//behavior:");
|
cc.comment("//behavior:");
|
||||||
/*generate 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));
|
auto PC_val_v = (uint32_t)(PC+(int16_t)sext<12>(imm));
|
||||||
mov(cc, jh.next_pc, PC_val_v);
|
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;
|
auto returnValue = BRANCH;
|
||||||
|
|
||||||
gen_sync(jh, POST_SYNC, 74);
|
gen_sync(jh, POST_SYNC, 74);
|
||||||
|
@ -4189,6 +4202,7 @@ private:
|
||||||
gen_instr_prologue(jh);
|
gen_instr_prologue(jh);
|
||||||
cc.comment("//behavior:");
|
cc.comment("//behavior:");
|
||||||
/*generate behavior*/
|
/*generate behavior*/
|
||||||
|
mov(jh.cc, get_ptr_for(jh, traits::LAST_BRANCH), static_cast<int>(NO_JUMP));
|
||||||
auto label_merge = cc.newLabel();
|
auto label_merge = cc.newLabel();
|
||||||
cmp(cc, gen_operation(cc, eq, load_reg_from_mem(jh, traits::X0 + rs1+8), 0)
|
cmp(cc, gen_operation(cc, eq, load_reg_from_mem(jh, traits::X0 + rs1+8), 0)
|
||||||
,0);
|
,0);
|
||||||
|
@ -4196,7 +4210,7 @@ private:
|
||||||
{
|
{
|
||||||
auto PC_val_v = (uint32_t)(PC+(int16_t)sext<9>(imm));
|
auto PC_val_v = (uint32_t)(PC+(int16_t)sext<9>(imm));
|
||||||
mov(cc, jh.next_pc, PC_val_v);
|
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);
|
cc.bind(label_merge);
|
||||||
auto returnValue = BRANCH;
|
auto returnValue = BRANCH;
|
||||||
|
@ -4237,6 +4251,7 @@ private:
|
||||||
gen_instr_prologue(jh);
|
gen_instr_prologue(jh);
|
||||||
cc.comment("//behavior:");
|
cc.comment("//behavior:");
|
||||||
/*generate behavior*/
|
/*generate behavior*/
|
||||||
|
mov(jh.cc, get_ptr_for(jh, traits::LAST_BRANCH), static_cast<int>(NO_JUMP));
|
||||||
auto label_merge = cc.newLabel();
|
auto label_merge = cc.newLabel();
|
||||||
cmp(cc, gen_operation(cc, ne, load_reg_from_mem(jh, traits::X0 + rs1+8), 0)
|
cmp(cc, gen_operation(cc, ne, load_reg_from_mem(jh, traits::X0 + rs1+8), 0)
|
||||||
,0);
|
,0);
|
||||||
|
@ -4244,7 +4259,7 @@ private:
|
||||||
{
|
{
|
||||||
auto PC_val_v = (uint32_t)(PC+(int16_t)sext<9>(imm));
|
auto PC_val_v = (uint32_t)(PC+(int16_t)sext<9>(imm));
|
||||||
mov(cc, jh.next_pc, PC_val_v);
|
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);
|
cc.bind(label_merge);
|
||||||
auto returnValue = BRANCH;
|
auto returnValue = BRANCH;
|
||||||
|
@ -4429,12 +4444,13 @@ private:
|
||||||
gen_instr_prologue(jh);
|
gen_instr_prologue(jh);
|
||||||
cc.comment("//behavior:");
|
cc.comment("//behavior:");
|
||||||
/*generate 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)){
|
if(rs1&&rs1<static_cast<uint32_t>(traits::RFS)){
|
||||||
auto addr_mask = (uint32_t)- 2;
|
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)
|
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, 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{
|
else{
|
||||||
gen_raise(jh, 0, 2);
|
gen_raise(jh, 0, 2);
|
||||||
|
@ -4561,6 +4577,7 @@ private:
|
||||||
gen_instr_prologue(jh);
|
gen_instr_prologue(jh);
|
||||||
cc.comment("//behavior:");
|
cc.comment("//behavior:");
|
||||||
/*generate 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)){
|
if(rs1>=static_cast<uint32_t>(traits::RFS)){
|
||||||
gen_raise(jh, 0, static_cast<int32_t>(traits::RV_CAUSE_ILLEGAL_INSTRUCTION));
|
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)
|
auto PC_val_v = gen_operation(cc, band, new_pc, addr_mask)
|
||||||
;
|
;
|
||||||
mov(cc, jh.next_pc, PC_val_v);
|
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;
|
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, current_next_pc, get_ptr_for(jh, traits::NEXT_PC));
|
||||||
mov(cc, jh.next_pc, current_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);
|
cc.ret(jh.next_pc);
|
||||||
}
|
}
|
||||||
template <typename ARCH>
|
template <typename ARCH>
|
||||||
|
|
|
@ -449,6 +449,7 @@ private:
|
||||||
|
|
||||||
this->gen_instr_prologue();
|
this->gen_instr_prologue();
|
||||||
/*generate behavior*/
|
/*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)) {
|
if(rd>=static_cast<uint32_t>(traits::RFS)) {
|
||||||
this->gen_raise_trap(0, static_cast<int32_t>(traits::RV_CAUSE_ILLEGAL_INSTRUCTION));
|
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;
|
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,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;
|
bb = this->leave_blk;
|
||||||
|
@ -505,6 +506,7 @@ private:
|
||||||
|
|
||||||
this->gen_instr_prologue();
|
this->gen_instr_prologue();
|
||||||
/*generate behavior*/
|
/*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)) {
|
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));
|
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;
|
auto PC_val_v = new_pc;
|
||||||
this->builder.CreateStore(PC_val_v, get_reg_ptr(traits::NEXT_PC), false);
|
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.CreateBr(bb_merge);
|
||||||
this->builder.SetInsertPoint(bb_merge);
|
this->builder.SetInsertPoint(bb_merge);
|
||||||
|
@ -583,6 +585,7 @@ private:
|
||||||
|
|
||||||
this->gen_instr_prologue();
|
this->gen_instr_prologue();
|
||||||
/*generate behavior*/
|
/*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)) {
|
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));
|
this->gen_raise_trap(0, static_cast<int32_t>(traits::RV_CAUSE_ILLEGAL_INSTRUCTION));
|
||||||
}
|
}
|
||||||
|
@ -602,7 +605,7 @@ private:
|
||||||
else{
|
else{
|
||||||
auto PC_val_v = new_pc;
|
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,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.CreateBr(bb_merge);
|
||||||
|
@ -645,6 +648,7 @@ private:
|
||||||
|
|
||||||
this->gen_instr_prologue();
|
this->gen_instr_prologue();
|
||||||
/*generate behavior*/
|
/*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)) {
|
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));
|
this->gen_raise_trap(0, static_cast<int32_t>(traits::RV_CAUSE_ILLEGAL_INSTRUCTION));
|
||||||
}
|
}
|
||||||
|
@ -664,7 +668,7 @@ private:
|
||||||
else{
|
else{
|
||||||
auto PC_val_v = new_pc;
|
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,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.CreateBr(bb_merge);
|
||||||
|
@ -707,6 +711,7 @@ private:
|
||||||
|
|
||||||
this->gen_instr_prologue();
|
this->gen_instr_prologue();
|
||||||
/*generate behavior*/
|
/*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)) {
|
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));
|
this->gen_raise_trap(0, static_cast<int32_t>(traits::RV_CAUSE_ILLEGAL_INSTRUCTION));
|
||||||
}
|
}
|
||||||
|
@ -730,7 +735,7 @@ private:
|
||||||
else{
|
else{
|
||||||
auto PC_val_v = new_pc;
|
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,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.CreateBr(bb_merge);
|
||||||
|
@ -773,6 +778,7 @@ private:
|
||||||
|
|
||||||
this->gen_instr_prologue();
|
this->gen_instr_prologue();
|
||||||
/*generate behavior*/
|
/*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)) {
|
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));
|
this->gen_raise_trap(0, static_cast<int32_t>(traits::RV_CAUSE_ILLEGAL_INSTRUCTION));
|
||||||
}
|
}
|
||||||
|
@ -796,7 +802,7 @@ private:
|
||||||
else{
|
else{
|
||||||
auto PC_val_v = new_pc;
|
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,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.CreateBr(bb_merge);
|
||||||
|
@ -839,6 +845,7 @@ private:
|
||||||
|
|
||||||
this->gen_instr_prologue();
|
this->gen_instr_prologue();
|
||||||
/*generate behavior*/
|
/*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)) {
|
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));
|
this->gen_raise_trap(0, static_cast<int32_t>(traits::RV_CAUSE_ILLEGAL_INSTRUCTION));
|
||||||
}
|
}
|
||||||
|
@ -858,7 +865,7 @@ private:
|
||||||
else{
|
else{
|
||||||
auto PC_val_v = new_pc;
|
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,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.CreateBr(bb_merge);
|
||||||
|
@ -901,6 +908,7 @@ private:
|
||||||
|
|
||||||
this->gen_instr_prologue();
|
this->gen_instr_prologue();
|
||||||
/*generate behavior*/
|
/*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)) {
|
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));
|
this->gen_raise_trap(0, static_cast<int32_t>(traits::RV_CAUSE_ILLEGAL_INSTRUCTION));
|
||||||
}
|
}
|
||||||
|
@ -920,7 +928,7 @@ private:
|
||||||
else{
|
else{
|
||||||
auto PC_val_v = new_pc;
|
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,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.CreateBr(bb_merge);
|
||||||
|
@ -2431,6 +2439,7 @@ private:
|
||||||
|
|
||||||
this->gen_instr_prologue();
|
this->gen_instr_prologue();
|
||||||
/*generate behavior*/
|
/*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);
|
this->gen_raise_trap(0, 11);
|
||||||
bb = this->leave_blk;
|
bb = this->leave_blk;
|
||||||
auto returnValue = std::make_tuple(TRAP,nullptr);
|
auto returnValue = std::make_tuple(TRAP,nullptr);
|
||||||
|
@ -2465,6 +2474,7 @@ private:
|
||||||
|
|
||||||
this->gen_instr_prologue();
|
this->gen_instr_prologue();
|
||||||
/*generate behavior*/
|
/*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);
|
this->gen_raise_trap(0, 3);
|
||||||
bb = this->leave_blk;
|
bb = this->leave_blk;
|
||||||
auto returnValue = std::make_tuple(TRAP,nullptr);
|
auto returnValue = std::make_tuple(TRAP,nullptr);
|
||||||
|
@ -2499,6 +2509,7 @@ private:
|
||||||
|
|
||||||
this->gen_instr_prologue();
|
this->gen_instr_prologue();
|
||||||
/*generate behavior*/
|
/*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);
|
this->gen_leave_trap(3);
|
||||||
bb = this->leave_blk;
|
bb = this->leave_blk;
|
||||||
auto returnValue = std::make_tuple(TRAP,nullptr);
|
auto returnValue = std::make_tuple(TRAP,nullptr);
|
||||||
|
@ -3746,12 +3757,13 @@ private:
|
||||||
|
|
||||||
this->gen_instr_prologue();
|
this->gen_instr_prologue();
|
||||||
/*generate behavior*/
|
/*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->builder.CreateStore(
|
||||||
this->gen_const(32,(uint32_t)(PC+2)),
|
this->gen_const(32,(uint32_t)(PC+2)),
|
||||||
get_reg_ptr(1 + traits::X0), false);
|
get_reg_ptr(1 + traits::X0), false);
|
||||||
auto PC_val_v = (uint32_t)(PC+(int16_t)sext<12>(imm));
|
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,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;
|
bb = this->leave_blk;
|
||||||
auto returnValue = std::make_tuple(BRANCH,nullptr);
|
auto returnValue = std::make_tuple(BRANCH,nullptr);
|
||||||
|
|
||||||
|
@ -4276,9 +4288,10 @@ private:
|
||||||
|
|
||||||
this->gen_instr_prologue();
|
this->gen_instr_prologue();
|
||||||
/*generate behavior*/
|
/*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));
|
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,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;
|
bb = this->leave_blk;
|
||||||
auto returnValue = std::make_tuple(BRANCH,nullptr);
|
auto returnValue = std::make_tuple(BRANCH,nullptr);
|
||||||
|
|
||||||
|
@ -4315,6 +4328,7 @@ private:
|
||||||
|
|
||||||
this->gen_instr_prologue();
|
this->gen_instr_prologue();
|
||||||
/*generate behavior*/
|
/*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_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_then = BasicBlock::Create(this->mod->getContext(), "bb_then", this->func, bb_merge);
|
||||||
this->builder.CreateCondBr(this->gen_bool(this->builder.CreateICmp(ICmpInst::ICMP_EQ,
|
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));
|
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,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.CreateBr(bb_merge);
|
||||||
this->builder.SetInsertPoint(bb_merge);
|
this->builder.SetInsertPoint(bb_merge);
|
||||||
|
@ -4365,6 +4379,7 @@ private:
|
||||||
|
|
||||||
this->gen_instr_prologue();
|
this->gen_instr_prologue();
|
||||||
/*generate behavior*/
|
/*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_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_then = BasicBlock::Create(this->mod->getContext(), "bb_then", this->func, bb_merge);
|
||||||
this->builder.CreateCondBr(this->gen_bool(this->builder.CreateICmp(ICmpInst::ICMP_NE,
|
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));
|
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,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.CreateBr(bb_merge);
|
||||||
this->builder.SetInsertPoint(bb_merge);
|
this->builder.SetInsertPoint(bb_merge);
|
||||||
|
@ -4563,13 +4578,14 @@ private:
|
||||||
|
|
||||||
this->gen_instr_prologue();
|
this->gen_instr_prologue();
|
||||||
/*generate behavior*/
|
/*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;
|
if(rs1&&rs1<static_cast<uint32_t>(traits::RFS)){ auto addr_mask =(uint32_t)- 2;
|
||||||
auto PC_val_v = this->builder.CreateAnd(
|
auto PC_val_v = this->builder.CreateAnd(
|
||||||
this->gen_reg_load(rs1%static_cast<uint32_t>(traits::RFS)+ traits::X0, 0),
|
this->gen_reg_load(rs1%static_cast<uint32_t>(traits::RFS)+ traits::X0, 0),
|
||||||
this->gen_const(32,addr_mask))
|
this->gen_const(32,addr_mask))
|
||||||
;
|
;
|
||||||
this->builder.CreateStore(PC_val_v, get_reg_ptr(traits::NEXT_PC), false);
|
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{
|
else{
|
||||||
this->gen_raise_trap(0, 2);
|
this->gen_raise_trap(0, 2);
|
||||||
|
@ -4694,6 +4710,7 @@ private:
|
||||||
|
|
||||||
this->gen_instr_prologue();
|
this->gen_instr_prologue();
|
||||||
/*generate behavior*/
|
/*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)) {
|
if(rs1>=static_cast<uint32_t>(traits::RFS)) {
|
||||||
this->gen_raise_trap(0, static_cast<int32_t>(traits::RV_CAUSE_ILLEGAL_INSTRUCTION));
|
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->gen_const(32,addr_mask))
|
||||||
;
|
;
|
||||||
this->builder.CreateStore(PC_val_v, get_reg_ptr(traits::NEXT_PC), false);
|
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;
|
bb = this->leave_blk;
|
||||||
auto returnValue = std::make_tuple(BRANCH,nullptr);
|
auto returnValue = std::make_tuple(BRANCH,nullptr);
|
||||||
|
@ -4987,7 +5004,7 @@ template <typename ARCH>
|
||||||
void vm_impl<ARCH>::gen_leave_trap(unsigned lvl) {
|
void vm_impl<ARCH>::gen_leave_trap(unsigned lvl) {
|
||||||
std::vector<Value *> args{ this->core_ptr, ConstantInt::get(getContext(), APInt(64, 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.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>
|
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(cur_pc_val),
|
||||||
this->adj_to64(this->builder.CreateLoad(this->get_type(64),this->tval))};
|
this->adj_to64(this->builder.CreateLoad(this->get_type(64),this->tval))};
|
||||||
this->builder.CreateCall(this->mod->getFunction("enter_trap"), args);
|
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);
|
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);
|
this->builder.CreateRet(trap_addr_val);
|
||||||
|
|
|
@ -422,6 +422,7 @@ private:
|
||||||
gen_set_pc(tu, pc, traits::NEXT_PC);
|
gen_set_pc(tu, pc, traits::NEXT_PC);
|
||||||
tu.open_scope();
|
tu.open_scope();
|
||||||
this->gen_set_tval(tu, instr);
|
this->gen_set_tval(tu, instr);
|
||||||
|
tu.store(traits::LAST_BRANCH, tu.constant(static_cast<int>(NO_JUMP),32));
|
||||||
if(rd>=static_cast<uint32_t>(traits:: RFS)) {
|
if(rd>=static_cast<uint32_t>(traits:: RFS)) {
|
||||||
this->gen_raise_trap(tu, 0, static_cast<int32_t>(traits:: RV_CAUSE_ILLEGAL_INSTRUCTION));
|
this->gen_raise_trap(tu, 0, static_cast<int32_t>(traits:: RV_CAUSE_ILLEGAL_INSTRUCTION));
|
||||||
}
|
}
|
||||||
|
@ -437,7 +438,7 @@ private:
|
||||||
}
|
}
|
||||||
auto PC_val_v = tu.assignment("PC_val", new_pc,32);
|
auto PC_val_v = tu.assignment("PC_val", new_pc,32);
|
||||||
tu.store(traits::NEXT_PC, PC_val_v);
|
tu.store(traits::NEXT_PC, PC_val_v);
|
||||||
tu.store(traits::LAST_BRANCH, tu.constant(2U, 2));
|
tu.store(traits::LAST_BRANCH, tu.constant(static_cast<int>(KNOWN_JUMP), 2));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
auto returnValue = std::make_tuple(BRANCH);
|
auto returnValue = std::make_tuple(BRANCH);
|
||||||
|
@ -468,6 +469,7 @@ private:
|
||||||
gen_set_pc(tu, pc, traits::NEXT_PC);
|
gen_set_pc(tu, pc, traits::NEXT_PC);
|
||||||
tu.open_scope();
|
tu.open_scope();
|
||||||
this->gen_set_tval(tu, instr);
|
this->gen_set_tval(tu, instr);
|
||||||
|
tu.store(traits::LAST_BRANCH, tu.constant(static_cast<int>(NO_JUMP),32));
|
||||||
if(rd>=static_cast<uint32_t>(traits:: RFS)||rs1>=static_cast<uint32_t>(traits:: RFS)) {
|
if(rd>=static_cast<uint32_t>(traits:: RFS)||rs1>=static_cast<uint32_t>(traits:: RFS)) {
|
||||||
this->gen_raise_trap(tu, 0, static_cast<int32_t>(traits:: RV_CAUSE_ILLEGAL_INSTRUCTION));
|
this->gen_raise_trap(tu, 0, static_cast<int32_t>(traits:: RV_CAUSE_ILLEGAL_INSTRUCTION));
|
||||||
}
|
}
|
||||||
|
@ -490,7 +492,7 @@ private:
|
||||||
}
|
}
|
||||||
auto PC_val_v = tu.assignment("PC_val", new_pc,32);
|
auto PC_val_v = tu.assignment("PC_val", new_pc,32);
|
||||||
tu.store(traits::NEXT_PC, PC_val_v);
|
tu.store(traits::NEXT_PC, PC_val_v);
|
||||||
tu.store(traits::LAST_BRANCH, tu.constant(2U, 2));
|
tu.store(traits::LAST_BRANCH, tu.constant(static_cast<int>(UNKNOWN_JUMP), 2));
|
||||||
tu.close_scope();
|
tu.close_scope();
|
||||||
}
|
}
|
||||||
auto returnValue = std::make_tuple(BRANCH);
|
auto returnValue = std::make_tuple(BRANCH);
|
||||||
|
@ -521,6 +523,7 @@ private:
|
||||||
gen_set_pc(tu, pc, traits::NEXT_PC);
|
gen_set_pc(tu, pc, traits::NEXT_PC);
|
||||||
tu.open_scope();
|
tu.open_scope();
|
||||||
this->gen_set_tval(tu, instr);
|
this->gen_set_tval(tu, instr);
|
||||||
|
tu.store(traits::LAST_BRANCH, tu.constant(static_cast<int>(NO_JUMP),32));
|
||||||
if(rs2>=static_cast<uint32_t>(traits:: RFS)||rs1>=static_cast<uint32_t>(traits:: RFS)) {
|
if(rs2>=static_cast<uint32_t>(traits:: RFS)||rs1>=static_cast<uint32_t>(traits:: RFS)) {
|
||||||
this->gen_raise_trap(tu, 0, static_cast<int32_t>(traits:: RV_CAUSE_ILLEGAL_INSTRUCTION));
|
this->gen_raise_trap(tu, 0, static_cast<int32_t>(traits:: RV_CAUSE_ILLEGAL_INSTRUCTION));
|
||||||
}
|
}
|
||||||
|
@ -535,7 +538,7 @@ private:
|
||||||
else{
|
else{
|
||||||
auto PC_val_v = tu.assignment("PC_val", new_pc,32);
|
auto PC_val_v = tu.assignment("PC_val", new_pc,32);
|
||||||
tu.store(traits::NEXT_PC, PC_val_v);
|
tu.store(traits::NEXT_PC, PC_val_v);
|
||||||
tu.store(traits::LAST_BRANCH, tu.constant(2U, 2));
|
tu.store(traits::LAST_BRANCH, tu.constant(static_cast<int>(KNOWN_JUMP), 2));
|
||||||
}
|
}
|
||||||
tu.close_scope();
|
tu.close_scope();
|
||||||
}
|
}
|
||||||
|
@ -567,6 +570,7 @@ private:
|
||||||
gen_set_pc(tu, pc, traits::NEXT_PC);
|
gen_set_pc(tu, pc, traits::NEXT_PC);
|
||||||
tu.open_scope();
|
tu.open_scope();
|
||||||
this->gen_set_tval(tu, instr);
|
this->gen_set_tval(tu, instr);
|
||||||
|
tu.store(traits::LAST_BRANCH, tu.constant(static_cast<int>(NO_JUMP),32));
|
||||||
if(rs2>=static_cast<uint32_t>(traits:: RFS)||rs1>=static_cast<uint32_t>(traits:: RFS)) {
|
if(rs2>=static_cast<uint32_t>(traits:: RFS)||rs1>=static_cast<uint32_t>(traits:: RFS)) {
|
||||||
this->gen_raise_trap(tu, 0, static_cast<int32_t>(traits:: RV_CAUSE_ILLEGAL_INSTRUCTION));
|
this->gen_raise_trap(tu, 0, static_cast<int32_t>(traits:: RV_CAUSE_ILLEGAL_INSTRUCTION));
|
||||||
}
|
}
|
||||||
|
@ -581,7 +585,7 @@ private:
|
||||||
else{
|
else{
|
||||||
auto PC_val_v = tu.assignment("PC_val", new_pc,32);
|
auto PC_val_v = tu.assignment("PC_val", new_pc,32);
|
||||||
tu.store(traits::NEXT_PC, PC_val_v);
|
tu.store(traits::NEXT_PC, PC_val_v);
|
||||||
tu.store(traits::LAST_BRANCH, tu.constant(2U, 2));
|
tu.store(traits::LAST_BRANCH, tu.constant(static_cast<int>(KNOWN_JUMP), 2));
|
||||||
}
|
}
|
||||||
tu.close_scope();
|
tu.close_scope();
|
||||||
}
|
}
|
||||||
|
@ -613,6 +617,7 @@ private:
|
||||||
gen_set_pc(tu, pc, traits::NEXT_PC);
|
gen_set_pc(tu, pc, traits::NEXT_PC);
|
||||||
tu.open_scope();
|
tu.open_scope();
|
||||||
this->gen_set_tval(tu, instr);
|
this->gen_set_tval(tu, instr);
|
||||||
|
tu.store(traits::LAST_BRANCH, tu.constant(static_cast<int>(NO_JUMP),32));
|
||||||
if(rs2>=static_cast<uint32_t>(traits:: RFS)||rs1>=static_cast<uint32_t>(traits:: RFS)) {
|
if(rs2>=static_cast<uint32_t>(traits:: RFS)||rs1>=static_cast<uint32_t>(traits:: RFS)) {
|
||||||
this->gen_raise_trap(tu, 0, static_cast<int32_t>(traits:: RV_CAUSE_ILLEGAL_INSTRUCTION));
|
this->gen_raise_trap(tu, 0, static_cast<int32_t>(traits:: RV_CAUSE_ILLEGAL_INSTRUCTION));
|
||||||
}
|
}
|
||||||
|
@ -627,7 +632,7 @@ private:
|
||||||
else{
|
else{
|
||||||
auto PC_val_v = tu.assignment("PC_val", new_pc,32);
|
auto PC_val_v = tu.assignment("PC_val", new_pc,32);
|
||||||
tu.store(traits::NEXT_PC, PC_val_v);
|
tu.store(traits::NEXT_PC, PC_val_v);
|
||||||
tu.store(traits::LAST_BRANCH, tu.constant(2U, 2));
|
tu.store(traits::LAST_BRANCH, tu.constant(static_cast<int>(KNOWN_JUMP), 2));
|
||||||
}
|
}
|
||||||
tu.close_scope();
|
tu.close_scope();
|
||||||
}
|
}
|
||||||
|
@ -659,6 +664,7 @@ private:
|
||||||
gen_set_pc(tu, pc, traits::NEXT_PC);
|
gen_set_pc(tu, pc, traits::NEXT_PC);
|
||||||
tu.open_scope();
|
tu.open_scope();
|
||||||
this->gen_set_tval(tu, instr);
|
this->gen_set_tval(tu, instr);
|
||||||
|
tu.store(traits::LAST_BRANCH, tu.constant(static_cast<int>(NO_JUMP),32));
|
||||||
if(rs2>=static_cast<uint32_t>(traits:: RFS)||rs1>=static_cast<uint32_t>(traits:: RFS)) {
|
if(rs2>=static_cast<uint32_t>(traits:: RFS)||rs1>=static_cast<uint32_t>(traits:: RFS)) {
|
||||||
this->gen_raise_trap(tu, 0, static_cast<int32_t>(traits:: RV_CAUSE_ILLEGAL_INSTRUCTION));
|
this->gen_raise_trap(tu, 0, static_cast<int32_t>(traits:: RV_CAUSE_ILLEGAL_INSTRUCTION));
|
||||||
}
|
}
|
||||||
|
@ -673,7 +679,7 @@ private:
|
||||||
else{
|
else{
|
||||||
auto PC_val_v = tu.assignment("PC_val", new_pc,32);
|
auto PC_val_v = tu.assignment("PC_val", new_pc,32);
|
||||||
tu.store(traits::NEXT_PC, PC_val_v);
|
tu.store(traits::NEXT_PC, PC_val_v);
|
||||||
tu.store(traits::LAST_BRANCH, tu.constant(2U, 2));
|
tu.store(traits::LAST_BRANCH, tu.constant(static_cast<int>(KNOWN_JUMP), 2));
|
||||||
}
|
}
|
||||||
tu.close_scope();
|
tu.close_scope();
|
||||||
}
|
}
|
||||||
|
@ -705,6 +711,7 @@ private:
|
||||||
gen_set_pc(tu, pc, traits::NEXT_PC);
|
gen_set_pc(tu, pc, traits::NEXT_PC);
|
||||||
tu.open_scope();
|
tu.open_scope();
|
||||||
this->gen_set_tval(tu, instr);
|
this->gen_set_tval(tu, instr);
|
||||||
|
tu.store(traits::LAST_BRANCH, tu.constant(static_cast<int>(NO_JUMP),32));
|
||||||
if(rs2>=static_cast<uint32_t>(traits:: RFS)||rs1>=static_cast<uint32_t>(traits:: RFS)) {
|
if(rs2>=static_cast<uint32_t>(traits:: RFS)||rs1>=static_cast<uint32_t>(traits:: RFS)) {
|
||||||
this->gen_raise_trap(tu, 0, static_cast<int32_t>(traits:: RV_CAUSE_ILLEGAL_INSTRUCTION));
|
this->gen_raise_trap(tu, 0, static_cast<int32_t>(traits:: RV_CAUSE_ILLEGAL_INSTRUCTION));
|
||||||
}
|
}
|
||||||
|
@ -719,7 +726,7 @@ private:
|
||||||
else{
|
else{
|
||||||
auto PC_val_v = tu.assignment("PC_val", new_pc,32);
|
auto PC_val_v = tu.assignment("PC_val", new_pc,32);
|
||||||
tu.store(traits::NEXT_PC, PC_val_v);
|
tu.store(traits::NEXT_PC, PC_val_v);
|
||||||
tu.store(traits::LAST_BRANCH, tu.constant(2U, 2));
|
tu.store(traits::LAST_BRANCH, tu.constant(static_cast<int>(KNOWN_JUMP), 2));
|
||||||
}
|
}
|
||||||
tu.close_scope();
|
tu.close_scope();
|
||||||
}
|
}
|
||||||
|
@ -751,6 +758,7 @@ private:
|
||||||
gen_set_pc(tu, pc, traits::NEXT_PC);
|
gen_set_pc(tu, pc, traits::NEXT_PC);
|
||||||
tu.open_scope();
|
tu.open_scope();
|
||||||
this->gen_set_tval(tu, instr);
|
this->gen_set_tval(tu, instr);
|
||||||
|
tu.store(traits::LAST_BRANCH, tu.constant(static_cast<int>(NO_JUMP),32));
|
||||||
if(rs2>=static_cast<uint32_t>(traits:: RFS)||rs1>=static_cast<uint32_t>(traits:: RFS)) {
|
if(rs2>=static_cast<uint32_t>(traits:: RFS)||rs1>=static_cast<uint32_t>(traits:: RFS)) {
|
||||||
this->gen_raise_trap(tu, 0, static_cast<int32_t>(traits:: RV_CAUSE_ILLEGAL_INSTRUCTION));
|
this->gen_raise_trap(tu, 0, static_cast<int32_t>(traits:: RV_CAUSE_ILLEGAL_INSTRUCTION));
|
||||||
}
|
}
|
||||||
|
@ -765,7 +773,7 @@ private:
|
||||||
else{
|
else{
|
||||||
auto PC_val_v = tu.assignment("PC_val", new_pc,32);
|
auto PC_val_v = tu.assignment("PC_val", new_pc,32);
|
||||||
tu.store(traits::NEXT_PC, PC_val_v);
|
tu.store(traits::NEXT_PC, PC_val_v);
|
||||||
tu.store(traits::LAST_BRANCH, tu.constant(2U, 2));
|
tu.store(traits::LAST_BRANCH, tu.constant(static_cast<int>(KNOWN_JUMP), 2));
|
||||||
}
|
}
|
||||||
tu.close_scope();
|
tu.close_scope();
|
||||||
}
|
}
|
||||||
|
@ -1885,6 +1893,7 @@ private:
|
||||||
gen_set_pc(tu, pc, traits::NEXT_PC);
|
gen_set_pc(tu, pc, traits::NEXT_PC);
|
||||||
tu.open_scope();
|
tu.open_scope();
|
||||||
this->gen_set_tval(tu, instr);
|
this->gen_set_tval(tu, instr);
|
||||||
|
tu.store(traits::LAST_BRANCH, tu.constant(static_cast<int>(NO_JUMP),32));
|
||||||
this->gen_raise_trap(tu, 0, 11);
|
this->gen_raise_trap(tu, 0, 11);
|
||||||
auto returnValue = std::make_tuple(TRAP);
|
auto returnValue = std::make_tuple(TRAP);
|
||||||
|
|
||||||
|
@ -1908,6 +1917,7 @@ private:
|
||||||
gen_set_pc(tu, pc, traits::NEXT_PC);
|
gen_set_pc(tu, pc, traits::NEXT_PC);
|
||||||
tu.open_scope();
|
tu.open_scope();
|
||||||
this->gen_set_tval(tu, instr);
|
this->gen_set_tval(tu, instr);
|
||||||
|
tu.store(traits::LAST_BRANCH, tu.constant(static_cast<int>(NO_JUMP),32));
|
||||||
this->gen_raise_trap(tu, 0, 3);
|
this->gen_raise_trap(tu, 0, 3);
|
||||||
auto returnValue = std::make_tuple(TRAP);
|
auto returnValue = std::make_tuple(TRAP);
|
||||||
|
|
||||||
|
@ -1931,6 +1941,7 @@ private:
|
||||||
gen_set_pc(tu, pc, traits::NEXT_PC);
|
gen_set_pc(tu, pc, traits::NEXT_PC);
|
||||||
tu.open_scope();
|
tu.open_scope();
|
||||||
this->gen_set_tval(tu, instr);
|
this->gen_set_tval(tu, instr);
|
||||||
|
tu.store(traits::LAST_BRANCH, tu.constant(static_cast<int>(NO_JUMP),32));
|
||||||
this->gen_leave_trap(tu, 3);
|
this->gen_leave_trap(tu, 3);
|
||||||
auto returnValue = std::make_tuple(TRAP);
|
auto returnValue = std::make_tuple(TRAP);
|
||||||
|
|
||||||
|
@ -2810,11 +2821,12 @@ private:
|
||||||
gen_set_pc(tu, pc, traits::NEXT_PC);
|
gen_set_pc(tu, pc, traits::NEXT_PC);
|
||||||
tu.open_scope();
|
tu.open_scope();
|
||||||
this->gen_set_tval(tu, instr);
|
this->gen_set_tval(tu, instr);
|
||||||
|
tu.store(traits::LAST_BRANCH, tu.constant(static_cast<int>(NO_JUMP),32));
|
||||||
tu.store(1 + traits::X0,
|
tu.store(1 + traits::X0,
|
||||||
tu.constant((uint32_t)(PC+2),32));
|
tu.constant((uint32_t)(PC+2),32));
|
||||||
auto PC_val_v = tu.assignment("PC_val", (uint32_t)(PC+(int16_t)sext<12>(imm)),32);
|
auto PC_val_v = tu.assignment("PC_val", (uint32_t)(PC+(int16_t)sext<12>(imm)),32);
|
||||||
tu.store(traits::NEXT_PC, PC_val_v);
|
tu.store(traits::NEXT_PC, PC_val_v);
|
||||||
tu.store(traits::LAST_BRANCH, tu.constant(2U, 2));
|
tu.store(traits::LAST_BRANCH, tu.constant(static_cast<int>(KNOWN_JUMP), 2));
|
||||||
auto returnValue = std::make_tuple(BRANCH);
|
auto returnValue = std::make_tuple(BRANCH);
|
||||||
|
|
||||||
tu.close_scope();
|
tu.close_scope();
|
||||||
|
@ -3195,9 +3207,10 @@ private:
|
||||||
gen_set_pc(tu, pc, traits::NEXT_PC);
|
gen_set_pc(tu, pc, traits::NEXT_PC);
|
||||||
tu.open_scope();
|
tu.open_scope();
|
||||||
this->gen_set_tval(tu, instr);
|
this->gen_set_tval(tu, instr);
|
||||||
|
tu.store(traits::LAST_BRANCH, tu.constant(static_cast<int>(NO_JUMP),32));
|
||||||
auto PC_val_v = tu.assignment("PC_val", (uint32_t)(PC+(int16_t)sext<12>(imm)),32);
|
auto PC_val_v = tu.assignment("PC_val", (uint32_t)(PC+(int16_t)sext<12>(imm)),32);
|
||||||
tu.store(traits::NEXT_PC, PC_val_v);
|
tu.store(traits::NEXT_PC, PC_val_v);
|
||||||
tu.store(traits::LAST_BRANCH, tu.constant(2U, 2));
|
tu.store(traits::LAST_BRANCH, tu.constant(static_cast<int>(KNOWN_JUMP), 2));
|
||||||
auto returnValue = std::make_tuple(BRANCH);
|
auto returnValue = std::make_tuple(BRANCH);
|
||||||
|
|
||||||
tu.close_scope();
|
tu.close_scope();
|
||||||
|
@ -3225,12 +3238,13 @@ private:
|
||||||
gen_set_pc(tu, pc, traits::NEXT_PC);
|
gen_set_pc(tu, pc, traits::NEXT_PC);
|
||||||
tu.open_scope();
|
tu.open_scope();
|
||||||
this->gen_set_tval(tu, instr);
|
this->gen_set_tval(tu, instr);
|
||||||
|
tu.store(traits::LAST_BRANCH, tu.constant(static_cast<int>(NO_JUMP),32));
|
||||||
tu.open_if(tu.icmp(ICmpInst::ICMP_EQ,
|
tu.open_if(tu.icmp(ICmpInst::ICMP_EQ,
|
||||||
tu.load(rs1+8+ traits::X0, 0),
|
tu.load(rs1+8+ traits::X0, 0),
|
||||||
tu.constant(0,8)));
|
tu.constant(0,8)));
|
||||||
auto PC_val_v = tu.assignment("PC_val", (uint32_t)(PC+(int16_t)sext<9>(imm)),32);
|
auto PC_val_v = tu.assignment("PC_val", (uint32_t)(PC+(int16_t)sext<9>(imm)),32);
|
||||||
tu.store(traits::NEXT_PC, PC_val_v);
|
tu.store(traits::NEXT_PC, PC_val_v);
|
||||||
tu.store(traits::LAST_BRANCH, tu.constant(2U, 2));
|
tu.store(traits::LAST_BRANCH, tu.constant(static_cast<int>(KNOWN_JUMP), 2));
|
||||||
tu.close_scope();
|
tu.close_scope();
|
||||||
auto returnValue = std::make_tuple(BRANCH);
|
auto returnValue = std::make_tuple(BRANCH);
|
||||||
|
|
||||||
|
@ -3259,12 +3273,13 @@ private:
|
||||||
gen_set_pc(tu, pc, traits::NEXT_PC);
|
gen_set_pc(tu, pc, traits::NEXT_PC);
|
||||||
tu.open_scope();
|
tu.open_scope();
|
||||||
this->gen_set_tval(tu, instr);
|
this->gen_set_tval(tu, instr);
|
||||||
|
tu.store(traits::LAST_BRANCH, tu.constant(static_cast<int>(NO_JUMP),32));
|
||||||
tu.open_if(tu.icmp(ICmpInst::ICMP_NE,
|
tu.open_if(tu.icmp(ICmpInst::ICMP_NE,
|
||||||
tu.load(rs1+8+ traits::X0, 0),
|
tu.load(rs1+8+ traits::X0, 0),
|
||||||
tu.constant(0,8)));
|
tu.constant(0,8)));
|
||||||
auto PC_val_v = tu.assignment("PC_val", (uint32_t)(PC+(int16_t)sext<9>(imm)),32);
|
auto PC_val_v = tu.assignment("PC_val", (uint32_t)(PC+(int16_t)sext<9>(imm)),32);
|
||||||
tu.store(traits::NEXT_PC, PC_val_v);
|
tu.store(traits::NEXT_PC, PC_val_v);
|
||||||
tu.store(traits::LAST_BRANCH, tu.constant(2U, 2));
|
tu.store(traits::LAST_BRANCH, tu.constant(static_cast<int>(KNOWN_JUMP), 2));
|
||||||
tu.close_scope();
|
tu.close_scope();
|
||||||
auto returnValue = std::make_tuple(BRANCH);
|
auto returnValue = std::make_tuple(BRANCH);
|
||||||
|
|
||||||
|
@ -3403,12 +3418,13 @@ private:
|
||||||
gen_set_pc(tu, pc, traits::NEXT_PC);
|
gen_set_pc(tu, pc, traits::NEXT_PC);
|
||||||
tu.open_scope();
|
tu.open_scope();
|
||||||
this->gen_set_tval(tu, instr);
|
this->gen_set_tval(tu, instr);
|
||||||
|
tu.store(traits::LAST_BRANCH, tu.constant(static_cast<int>(NO_JUMP),32));
|
||||||
if(rs1&&rs1<static_cast<uint32_t>(traits:: RFS)){ auto addr_mask = (uint32_t)- 2;
|
if(rs1&&rs1<static_cast<uint32_t>(traits:: RFS)){ auto addr_mask = (uint32_t)- 2;
|
||||||
auto PC_val_v = tu.assignment("PC_val", tu.bitwise_and(
|
auto PC_val_v = tu.assignment("PC_val", tu.bitwise_and(
|
||||||
tu.load(rs1%static_cast<uint32_t>(traits:: RFS)+ traits::X0, 0),
|
tu.load(rs1%static_cast<uint32_t>(traits:: RFS)+ traits::X0, 0),
|
||||||
tu.constant(addr_mask,32)),32);
|
tu.constant(addr_mask,32)),32);
|
||||||
tu.store(traits::NEXT_PC, PC_val_v);
|
tu.store(traits::NEXT_PC, PC_val_v);
|
||||||
tu.store(traits::LAST_BRANCH, tu.constant(2U, 2));
|
tu.store(traits::LAST_BRANCH, tu.constant(static_cast<int>(UNKNOWN_JUMP), 2));
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
this->gen_raise_trap(tu, 0, 2);
|
this->gen_raise_trap(tu, 0, 2);
|
||||||
|
@ -3500,6 +3516,7 @@ private:
|
||||||
gen_set_pc(tu, pc, traits::NEXT_PC);
|
gen_set_pc(tu, pc, traits::NEXT_PC);
|
||||||
tu.open_scope();
|
tu.open_scope();
|
||||||
this->gen_set_tval(tu, instr);
|
this->gen_set_tval(tu, instr);
|
||||||
|
tu.store(traits::LAST_BRANCH, tu.constant(static_cast<int>(NO_JUMP),32));
|
||||||
if(rs1>=static_cast<uint32_t>(traits:: RFS)) {
|
if(rs1>=static_cast<uint32_t>(traits:: RFS)) {
|
||||||
this->gen_raise_trap(tu, 0, static_cast<int32_t>(traits:: RV_CAUSE_ILLEGAL_INSTRUCTION));
|
this->gen_raise_trap(tu, 0, static_cast<int32_t>(traits:: RV_CAUSE_ILLEGAL_INSTRUCTION));
|
||||||
}
|
}
|
||||||
|
@ -3512,7 +3529,7 @@ private:
|
||||||
new_pc,
|
new_pc,
|
||||||
tu.constant(addr_mask,32)),32);
|
tu.constant(addr_mask,32)),32);
|
||||||
tu.store(traits::NEXT_PC, PC_val_v);
|
tu.store(traits::NEXT_PC, PC_val_v);
|
||||||
tu.store(traits::LAST_BRANCH, tu.constant(2U, 2));
|
tu.store(traits::LAST_BRANCH, tu.constant(static_cast<int>(UNKNOWN_JUMP), 2));
|
||||||
}
|
}
|
||||||
auto returnValue = std::make_tuple(BRANCH);
|
auto returnValue = std::make_tuple(BRANCH);
|
||||||
|
|
||||||
|
@ -3724,13 +3741,12 @@ vm_impl<ARCH>::gen_single_inst_behavior(virt_addr_t &pc, unsigned int &inst_cnt,
|
||||||
|
|
||||||
template <typename ARCH> void vm_impl<ARCH>::gen_raise_trap(tu_builder& tu, uint16_t trap_id, uint16_t cause) {
|
template <typename ARCH> void vm_impl<ARCH>::gen_raise_trap(tu_builder& tu, uint16_t trap_id, uint16_t cause) {
|
||||||
tu(" *trap_state = {:#x};", 0x80 << 24 | (cause << 16) | trap_id);
|
tu(" *trap_state = {:#x};", 0x80 << 24 | (cause << 16) | trap_id);
|
||||||
tu.store(traits::NEXT_PC, tu.constant(std::numeric_limits<uint32_t>::max(), 32));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename ARCH> void vm_impl<ARCH>::gen_leave_trap(tu_builder& tu, unsigned lvl) {
|
template <typename ARCH> void vm_impl<ARCH>::gen_leave_trap(tu_builder& tu, unsigned lvl) {
|
||||||
tu("leave_trap(core_ptr, {});", lvl);
|
tu("leave_trap(core_ptr, {});", lvl);
|
||||||
tu.store(traits::NEXT_PC, tu.read_mem(traits::CSR, (lvl << 8) + 0x41, traits::XLEN));
|
tu.store(traits::NEXT_PC, tu.read_mem(traits::CSR, (lvl << 8) + 0x41, traits::XLEN));
|
||||||
tu.store(traits::LAST_BRANCH, tu.constant(std::numeric_limits<uint32_t>::max(), 32));
|
tu.store(traits::LAST_BRANCH, tu.constant(static_cast<int>(UNKNOWN_JUMP), 32));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename ARCH> void vm_impl<ARCH>::gen_wait(tu_builder& tu, unsigned type) {
|
template <typename ARCH> void vm_impl<ARCH>::gen_wait(tu_builder& tu, unsigned type) {
|
||||||
|
@ -3747,7 +3763,7 @@ template <typename ARCH> void vm_impl<ARCH>::gen_trap_behavior(tu_builder& tu) {
|
||||||
tu("trap_entry:");
|
tu("trap_entry:");
|
||||||
this->gen_sync(tu, POST_SYNC, -1);
|
this->gen_sync(tu, POST_SYNC, -1);
|
||||||
tu("enter_trap(core_ptr, *trap_state, *pc, tval);");
|
tu("enter_trap(core_ptr, *trap_state, *pc, tval);");
|
||||||
tu.store(traits::LAST_BRANCH, tu.constant(std::numeric_limits<uint32_t>::max(),32));
|
tu.store(traits::LAST_BRANCH, tu.constant(static_cast<int>(UNKNOWN_JUMP),32));
|
||||||
tu("return *next_pc;");
|
tu("return *next_pc;");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue