Compare commits
	
		
			1 Commits
		
	
	
		
			4f5d9214ed
			...
			0432803d82
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 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;"); | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user