From e1b6cab890d2ecd14d4e64047ee7feb5c7d8521b Mon Sep 17 00:00:00 2001 From: Eyck-Alexander Jentzsch Date: Thu, 18 Jul 2024 12:02:40 +0200 Subject: [PATCH] removes setting of NEXT_PC to max when trapping in llvm and asmjit, adds default disass to llvm --- gen_input/templates/asmjit/CORENAME.cpp.gtl | 1 - gen_input/templates/llvm/CORENAME.cpp.gtl | 38 +- src/vm/asmjit/vm_tgc5c.cpp | 1 - src/vm/llvm/vm_tgc5c.cpp | 783 +++++++++++++------- 4 files changed, 545 insertions(+), 278 deletions(-) diff --git a/gen_input/templates/asmjit/CORENAME.cpp.gtl b/gen_input/templates/asmjit/CORENAME.cpp.gtl index 74e5588..eb7cb3d 100644 --- a/gen_input/templates/asmjit/CORENAME.cpp.gtl +++ b/gen_input/templates/asmjit/CORENAME.cpp.gtl @@ -357,7 +357,6 @@ inline void vm_impl::gen_raise(jit_holder& jh, uint16_t trap_id, uint16_t auto tmp1 = get_reg_for(cc, traits::TRAP_STATE); mov(cc, tmp1, 0x80ULL << 24 | (cause << 16) | trap_id); mov(cc, get_ptr_for(jh, traits::TRAP_STATE), tmp1); - mov(cc, jh.next_pc, std::numeric_limits::max()); } } // namespace tgc5c diff --git a/gen_input/templates/llvm/CORENAME.cpp.gtl b/gen_input/templates/llvm/CORENAME.cpp.gtl index 07601c1..0c7f3e0 100644 --- a/gen_input/templates/llvm/CORENAME.cpp.gtl +++ b/gen_input/templates/llvm/CORENAME.cpp.gtl @@ -105,6 +105,7 @@ protected: void set_tval(uint64_t new_tval); void set_tval(Value* new_tval); void gen_trap_behavior(BasicBlock *) override; + void gen_instr_prologue(); void gen_instr_epilogue(BasicBlock *bb); inline Value *gen_reg_load(unsigned i, unsigned level = 0) { @@ -164,14 +165,22 @@ private: <%}%>if(this->disass_enabled){ /* generate console output when executing the command */<%instr.disass.eachLine{%> ${it}<%}%> + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } bb->setName(fmt::format("${instr.name}_0x{:X}",pc.val)); this->gen_sync(PRE_SYNC,${idx}); - auto cur_pc_val = this->gen_const(32,pc.val); + + this->gen_set_pc(pc, traits::PC); + this->set_tval(instr); pc=pc+ ${instr.length/8}; this->gen_set_pc(pc, traits::NEXT_PC); - this->set_tval(instr); - + + this->gen_instr_prologue(); /*generate behavior*/ <%instr.behavior.eachLine{%>${it} <%}%> @@ -321,15 +330,12 @@ template void vm_impl::gen_raise_trap(uint16_t trap_id, uint16_t cause) { auto *TRAP_val = this->gen_const(32, 0x80 << 24 | (cause << 16) | trap_id); this->builder.CreateStore(TRAP_val, get_reg_ptr(traits::TRAP_STATE), true); - this->builder.CreateStore(this->gen_const(32U, std::numeric_limits::max()), get_reg_ptr(traits::LAST_BRANCH), false); } template void vm_impl::gen_leave_trap(unsigned lvl) { std::vector args{ this->core_ptr, ConstantInt::get(getContext(), APInt(64, lvl)) }; this->builder.CreateCall(this->mod->getFunction("leave_trap"), args); - auto *PC_val = this->gen_read_mem(traits::CSR, (lvl << 8) + 0x41, traits::XLEN / 8); - this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); this->builder.CreateStore(this->gen_const(32U, std::numeric_limits::max()), get_reg_ptr(traits::LAST_BRANCH), false); } @@ -352,14 +358,24 @@ template void vm_impl::gen_trap_behavior(BasicBlock *trap_blk) { this->builder.SetInsertPoint(trap_blk); auto *trap_state_val = this->builder.CreateLoad(this->get_typeptr(traits::TRAP_STATE), get_reg_ptr(traits::TRAP_STATE), true); - this->builder.CreateStore(this->gen_const(32U, std::numeric_limits::max()), - get_reg_ptr(traits::LAST_BRANCH), false); - std::vector args{this->core_ptr, this->adj_to64(trap_state_val), + auto *cur_pc_val = this->builder.CreateLoad(this->get_typeptr(traits::PC), get_reg_ptr(traits::PC), true); + std::vector args{this->core_ptr, + this->adj_to64(trap_state_val), + this->adj_to64(cur_pc_val), this->adj_to64(this->builder.CreateLoad(this->get_type(64),this->tval))}; this->builder.CreateCall(this->mod->getFunction("enter_trap"), args); + this->builder.CreateStore(this->gen_const(32U, std::numeric_limits::max()), get_reg_ptr(traits::LAST_BRANCH), false); + auto *trap_addr_val = this->builder.CreateLoad(this->get_typeptr(traits::NEXT_PC), get_reg_ptr(traits::NEXT_PC), false); this->builder.CreateRet(trap_addr_val); } +template +void vm_impl::gen_instr_prologue() { + auto* trap_val = + this->builder.CreateLoad(this->get_typeptr(arch::traits::PENDING_TRAP), get_reg_ptr(arch::traits::PENDING_TRAP)); + this->builder.CreateStore(trap_val, get_reg_ptr(arch::traits::TRAP_STATE), false); +} + template void vm_impl::gen_instr_epilogue(BasicBlock *bb) { @@ -370,6 +386,10 @@ void vm_impl::gen_instr_epilogue(BasicBlock *bb) { ConstantInt::get(getContext(), APInt(v->getType()->getIntegerBitWidth(), 0))), target_bb, this->trap_blk, 1); this->builder.SetInsertPoint(target_bb); + // update icount + auto* icount_val = this->builder.CreateAdd( + this->builder.CreateLoad(this->get_typeptr(arch::traits::ICOUNT), get_reg_ptr(arch::traits::ICOUNT)), this->gen_const(64U, 1)); + this->builder.CreateStore(icount_val, get_reg_ptr(arch::traits::ICOUNT), false); } } // namespace ${coreDef.name.toLowerCase()} diff --git a/src/vm/asmjit/vm_tgc5c.cpp b/src/vm/asmjit/vm_tgc5c.cpp index c8816e5..da56508 100644 --- a/src/vm/asmjit/vm_tgc5c.cpp +++ b/src/vm/asmjit/vm_tgc5c.cpp @@ -4880,7 +4880,6 @@ inline void vm_impl::gen_raise(jit_holder& jh, uint16_t trap_id, uint16_t auto tmp1 = get_reg_for(cc, traits::TRAP_STATE); mov(cc, tmp1, 0x80ULL << 24 | (cause << 16) | trap_id); mov(cc, get_ptr_for(jh, traits::TRAP_STATE), tmp1); - mov(cc, jh.next_pc, std::numeric_limits::max()); } } // namespace tgc5c diff --git a/src/vm/llvm/vm_tgc5c.cpp b/src/vm/llvm/vm_tgc5c.cpp index 4313a53..19bc91b 100644 --- a/src/vm/llvm/vm_tgc5c.cpp +++ b/src/vm/llvm/vm_tgc5c.cpp @@ -105,6 +105,7 @@ protected: void set_tval(uint64_t new_tval); void set_tval(Value* new_tval); void gen_trap_behavior(BasicBlock *) override; + void gen_instr_prologue(); void gen_instr_epilogue(BasicBlock *bb); inline Value *gen_reg_load(unsigned i, unsigned level = 0) { @@ -348,11 +349,13 @@ private: } bb->setName(fmt::format("LUI_0x{:X}",pc.val)); this->gen_sync(PRE_SYNC,0); - auto cur_pc_val = this->gen_const(32,pc.val); + + this->gen_set_pc(pc, traits::PC); + this->set_tval(instr); pc=pc+ 4; this->gen_set_pc(pc, traits::NEXT_PC); - this->set_tval(instr); - + + this->gen_instr_prologue(); /*generate behavior*/ if(rd>=static_cast(traits::RFS)) { this->gen_raise_trap(0, static_cast(traits::RV_CAUSE_ILLEGAL_INSTRUCTION)); @@ -392,11 +395,13 @@ private: } bb->setName(fmt::format("AUIPC_0x{:X}",pc.val)); this->gen_sync(PRE_SYNC,1); - auto cur_pc_val = this->gen_const(32,pc.val); + + this->gen_set_pc(pc, traits::PC); + this->set_tval(instr); pc=pc+ 4; this->gen_set_pc(pc, traits::NEXT_PC); - this->set_tval(instr); - + + this->gen_instr_prologue(); /*generate behavior*/ if(rd>=static_cast(traits::RFS)) { this->gen_raise_trap(0, static_cast(traits::RV_CAUSE_ILLEGAL_INSTRUCTION)); @@ -436,11 +441,13 @@ private: } bb->setName(fmt::format("JAL_0x{:X}",pc.val)); this->gen_sync(PRE_SYNC,2); - auto cur_pc_val = this->gen_const(32,pc.val); + + this->gen_set_pc(pc, traits::PC); + this->set_tval(instr); pc=pc+ 4; this->gen_set_pc(pc, traits::NEXT_PC); - this->set_tval(instr); - + + this->gen_instr_prologue(); /*generate behavior*/ if(rd>=static_cast(traits::RFS)) { this->gen_raise_trap(0, static_cast(traits::RV_CAUSE_ILLEGAL_INSTRUCTION)); @@ -490,11 +497,13 @@ private: } bb->setName(fmt::format("JALR_0x{:X}",pc.val)); this->gen_sync(PRE_SYNC,3); - auto cur_pc_val = this->gen_const(32,pc.val); + + this->gen_set_pc(pc, traits::PC); + this->set_tval(instr); pc=pc+ 4; this->gen_set_pc(pc, traits::NEXT_PC); - this->set_tval(instr); - + + this->gen_instr_prologue(); /*generate behavior*/ if(rd>=static_cast(traits::RFS)||rs1>=static_cast(traits::RFS)) { this->gen_raise_trap(0, static_cast(traits::RV_CAUSE_ILLEGAL_INSTRUCTION)); @@ -566,11 +575,13 @@ private: } bb->setName(fmt::format("BEQ_0x{:X}",pc.val)); this->gen_sync(PRE_SYNC,4); - auto cur_pc_val = this->gen_const(32,pc.val); + + this->gen_set_pc(pc, traits::PC); + this->set_tval(instr); pc=pc+ 4; this->gen_set_pc(pc, traits::NEXT_PC); - this->set_tval(instr); - + + this->gen_instr_prologue(); /*generate behavior*/ if(rs2>=static_cast(traits::RFS)||rs1>=static_cast(traits::RFS)) { this->gen_raise_trap(0, static_cast(traits::RV_CAUSE_ILLEGAL_INSTRUCTION)); @@ -626,11 +637,13 @@ private: } bb->setName(fmt::format("BNE_0x{:X}",pc.val)); this->gen_sync(PRE_SYNC,5); - auto cur_pc_val = this->gen_const(32,pc.val); + + this->gen_set_pc(pc, traits::PC); + this->set_tval(instr); pc=pc+ 4; this->gen_set_pc(pc, traits::NEXT_PC); - this->set_tval(instr); - + + this->gen_instr_prologue(); /*generate behavior*/ if(rs2>=static_cast(traits::RFS)||rs1>=static_cast(traits::RFS)) { this->gen_raise_trap(0, static_cast(traits::RV_CAUSE_ILLEGAL_INSTRUCTION)); @@ -686,11 +699,13 @@ private: } bb->setName(fmt::format("BLT_0x{:X}",pc.val)); this->gen_sync(PRE_SYNC,6); - auto cur_pc_val = this->gen_const(32,pc.val); + + this->gen_set_pc(pc, traits::PC); + this->set_tval(instr); pc=pc+ 4; this->gen_set_pc(pc, traits::NEXT_PC); - this->set_tval(instr); - + + this->gen_instr_prologue(); /*generate behavior*/ if(rs2>=static_cast(traits::RFS)||rs1>=static_cast(traits::RFS)) { this->gen_raise_trap(0, static_cast(traits::RV_CAUSE_ILLEGAL_INSTRUCTION)); @@ -750,11 +765,13 @@ private: } bb->setName(fmt::format("BGE_0x{:X}",pc.val)); this->gen_sync(PRE_SYNC,7); - auto cur_pc_val = this->gen_const(32,pc.val); + + this->gen_set_pc(pc, traits::PC); + this->set_tval(instr); pc=pc+ 4; this->gen_set_pc(pc, traits::NEXT_PC); - this->set_tval(instr); - + + this->gen_instr_prologue(); /*generate behavior*/ if(rs2>=static_cast(traits::RFS)||rs1>=static_cast(traits::RFS)) { this->gen_raise_trap(0, static_cast(traits::RV_CAUSE_ILLEGAL_INSTRUCTION)); @@ -814,11 +831,13 @@ private: } bb->setName(fmt::format("BLTU_0x{:X}",pc.val)); this->gen_sync(PRE_SYNC,8); - auto cur_pc_val = this->gen_const(32,pc.val); + + this->gen_set_pc(pc, traits::PC); + this->set_tval(instr); pc=pc+ 4; this->gen_set_pc(pc, traits::NEXT_PC); - this->set_tval(instr); - + + this->gen_instr_prologue(); /*generate behavior*/ if(rs2>=static_cast(traits::RFS)||rs1>=static_cast(traits::RFS)) { this->gen_raise_trap(0, static_cast(traits::RV_CAUSE_ILLEGAL_INSTRUCTION)); @@ -874,11 +893,13 @@ private: } bb->setName(fmt::format("BGEU_0x{:X}",pc.val)); this->gen_sync(PRE_SYNC,9); - auto cur_pc_val = this->gen_const(32,pc.val); + + this->gen_set_pc(pc, traits::PC); + this->set_tval(instr); pc=pc+ 4; this->gen_set_pc(pc, traits::NEXT_PC); - this->set_tval(instr); - + + this->gen_instr_prologue(); /*generate behavior*/ if(rs2>=static_cast(traits::RFS)||rs1>=static_cast(traits::RFS)) { this->gen_raise_trap(0, static_cast(traits::RV_CAUSE_ILLEGAL_INSTRUCTION)); @@ -934,11 +955,13 @@ private: } bb->setName(fmt::format("LB_0x{:X}",pc.val)); this->gen_sync(PRE_SYNC,10); - auto cur_pc_val = this->gen_const(32,pc.val); + + this->gen_set_pc(pc, traits::PC); + this->set_tval(instr); pc=pc+ 4; this->gen_set_pc(pc, traits::NEXT_PC); - this->set_tval(instr); - + + this->gen_instr_prologue(); /*generate behavior*/ if(rd>=static_cast(traits::RFS)||rs1>=static_cast(traits::RFS)) { this->gen_raise_trap(0, static_cast(traits::RV_CAUSE_ILLEGAL_INSTRUCTION)); @@ -990,11 +1013,13 @@ private: } bb->setName(fmt::format("LH_0x{:X}",pc.val)); this->gen_sync(PRE_SYNC,11); - auto cur_pc_val = this->gen_const(32,pc.val); + + this->gen_set_pc(pc, traits::PC); + this->set_tval(instr); pc=pc+ 4; this->gen_set_pc(pc, traits::NEXT_PC); - this->set_tval(instr); - + + this->gen_instr_prologue(); /*generate behavior*/ if(rd>=static_cast(traits::RFS)||rs1>=static_cast(traits::RFS)) { this->gen_raise_trap(0, static_cast(traits::RV_CAUSE_ILLEGAL_INSTRUCTION)); @@ -1046,11 +1071,13 @@ private: } bb->setName(fmt::format("LW_0x{:X}",pc.val)); this->gen_sync(PRE_SYNC,12); - auto cur_pc_val = this->gen_const(32,pc.val); + + this->gen_set_pc(pc, traits::PC); + this->set_tval(instr); pc=pc+ 4; this->gen_set_pc(pc, traits::NEXT_PC); - this->set_tval(instr); - + + this->gen_instr_prologue(); /*generate behavior*/ if(rd>=static_cast(traits::RFS)||rs1>=static_cast(traits::RFS)) { this->gen_raise_trap(0, static_cast(traits::RV_CAUSE_ILLEGAL_INSTRUCTION)); @@ -1102,11 +1129,13 @@ private: } bb->setName(fmt::format("LBU_0x{:X}",pc.val)); this->gen_sync(PRE_SYNC,13); - auto cur_pc_val = this->gen_const(32,pc.val); + + this->gen_set_pc(pc, traits::PC); + this->set_tval(instr); pc=pc+ 4; this->gen_set_pc(pc, traits::NEXT_PC); - this->set_tval(instr); - + + this->gen_instr_prologue(); /*generate behavior*/ if(rd>=static_cast(traits::RFS)||rs1>=static_cast(traits::RFS)) { this->gen_raise_trap(0, static_cast(traits::RV_CAUSE_ILLEGAL_INSTRUCTION)); @@ -1156,11 +1185,13 @@ private: } bb->setName(fmt::format("LHU_0x{:X}",pc.val)); this->gen_sync(PRE_SYNC,14); - auto cur_pc_val = this->gen_const(32,pc.val); + + this->gen_set_pc(pc, traits::PC); + this->set_tval(instr); pc=pc+ 4; this->gen_set_pc(pc, traits::NEXT_PC); - this->set_tval(instr); - + + this->gen_instr_prologue(); /*generate behavior*/ if(rd>=static_cast(traits::RFS)||rs1>=static_cast(traits::RFS)) { this->gen_raise_trap(0, static_cast(traits::RV_CAUSE_ILLEGAL_INSTRUCTION)); @@ -1210,11 +1241,13 @@ private: } bb->setName(fmt::format("SB_0x{:X}",pc.val)); this->gen_sync(PRE_SYNC,15); - auto cur_pc_val = this->gen_const(32,pc.val); + + this->gen_set_pc(pc, traits::PC); + this->set_tval(instr); pc=pc+ 4; this->gen_set_pc(pc, traits::NEXT_PC); - this->set_tval(instr); - + + this->gen_instr_prologue(); /*generate behavior*/ if(rs2>=static_cast(traits::RFS)||rs1>=static_cast(traits::RFS)) { this->gen_raise_trap(0, static_cast(traits::RV_CAUSE_ILLEGAL_INSTRUCTION)); @@ -1261,11 +1294,13 @@ private: } bb->setName(fmt::format("SH_0x{:X}",pc.val)); this->gen_sync(PRE_SYNC,16); - auto cur_pc_val = this->gen_const(32,pc.val); + + this->gen_set_pc(pc, traits::PC); + this->set_tval(instr); pc=pc+ 4; this->gen_set_pc(pc, traits::NEXT_PC); - this->set_tval(instr); - + + this->gen_instr_prologue(); /*generate behavior*/ if(rs2>=static_cast(traits::RFS)||rs1>=static_cast(traits::RFS)) { this->gen_raise_trap(0, static_cast(traits::RV_CAUSE_ILLEGAL_INSTRUCTION)); @@ -1312,11 +1347,13 @@ private: } bb->setName(fmt::format("SW_0x{:X}",pc.val)); this->gen_sync(PRE_SYNC,17); - auto cur_pc_val = this->gen_const(32,pc.val); + + this->gen_set_pc(pc, traits::PC); + this->set_tval(instr); pc=pc+ 4; this->gen_set_pc(pc, traits::NEXT_PC); - this->set_tval(instr); - + + this->gen_instr_prologue(); /*generate behavior*/ if(rs2>=static_cast(traits::RFS)||rs1>=static_cast(traits::RFS)) { this->gen_raise_trap(0, static_cast(traits::RV_CAUSE_ILLEGAL_INSTRUCTION)); @@ -1363,11 +1400,13 @@ private: } bb->setName(fmt::format("ADDI_0x{:X}",pc.val)); this->gen_sync(PRE_SYNC,18); - auto cur_pc_val = this->gen_const(32,pc.val); + + this->gen_set_pc(pc, traits::PC); + this->set_tval(instr); pc=pc+ 4; this->gen_set_pc(pc, traits::NEXT_PC); - this->set_tval(instr); - + + this->gen_instr_prologue(); /*generate behavior*/ if(rd>=static_cast(traits::RFS)||rs1>=static_cast(traits::RFS)) { this->gen_raise_trap(0, static_cast(traits::RV_CAUSE_ILLEGAL_INSTRUCTION)); @@ -1413,11 +1452,13 @@ private: } bb->setName(fmt::format("SLTI_0x{:X}",pc.val)); this->gen_sync(PRE_SYNC,19); - auto cur_pc_val = this->gen_const(32,pc.val); + + this->gen_set_pc(pc, traits::PC); + this->set_tval(instr); pc=pc+ 4; this->gen_set_pc(pc, traits::NEXT_PC); - this->set_tval(instr); - + + this->gen_instr_prologue(); /*generate behavior*/ if(rd>=static_cast(traits::RFS)||rs1>=static_cast(traits::RFS)) { this->gen_raise_trap(0, static_cast(traits::RV_CAUSE_ILLEGAL_INSTRUCTION)); @@ -1465,11 +1506,13 @@ private: } bb->setName(fmt::format("SLTIU_0x{:X}",pc.val)); this->gen_sync(PRE_SYNC,20); - auto cur_pc_val = this->gen_const(32,pc.val); + + this->gen_set_pc(pc, traits::PC); + this->set_tval(instr); pc=pc+ 4; this->gen_set_pc(pc, traits::NEXT_PC); - this->set_tval(instr); - + + this->gen_instr_prologue(); /*generate behavior*/ if(rd>=static_cast(traits::RFS)||rs1>=static_cast(traits::RFS)) { this->gen_raise_trap(0, static_cast(traits::RV_CAUSE_ILLEGAL_INSTRUCTION)); @@ -1516,11 +1559,13 @@ private: } bb->setName(fmt::format("XORI_0x{:X}",pc.val)); this->gen_sync(PRE_SYNC,21); - auto cur_pc_val = this->gen_const(32,pc.val); + + this->gen_set_pc(pc, traits::PC); + this->set_tval(instr); pc=pc+ 4; this->gen_set_pc(pc, traits::NEXT_PC); - this->set_tval(instr); - + + this->gen_instr_prologue(); /*generate behavior*/ if(rd>=static_cast(traits::RFS)||rs1>=static_cast(traits::RFS)) { this->gen_raise_trap(0, static_cast(traits::RV_CAUSE_ILLEGAL_INSTRUCTION)); @@ -1564,11 +1609,13 @@ private: } bb->setName(fmt::format("ORI_0x{:X}",pc.val)); this->gen_sync(PRE_SYNC,22); - auto cur_pc_val = this->gen_const(32,pc.val); + + this->gen_set_pc(pc, traits::PC); + this->set_tval(instr); pc=pc+ 4; this->gen_set_pc(pc, traits::NEXT_PC); - this->set_tval(instr); - + + this->gen_instr_prologue(); /*generate behavior*/ if(rd>=static_cast(traits::RFS)||rs1>=static_cast(traits::RFS)) { this->gen_raise_trap(0, static_cast(traits::RV_CAUSE_ILLEGAL_INSTRUCTION)); @@ -1612,11 +1659,13 @@ private: } bb->setName(fmt::format("ANDI_0x{:X}",pc.val)); this->gen_sync(PRE_SYNC,23); - auto cur_pc_val = this->gen_const(32,pc.val); + + this->gen_set_pc(pc, traits::PC); + this->set_tval(instr); pc=pc+ 4; this->gen_set_pc(pc, traits::NEXT_PC); - this->set_tval(instr); - + + this->gen_instr_prologue(); /*generate behavior*/ if(rd>=static_cast(traits::RFS)||rs1>=static_cast(traits::RFS)) { this->gen_raise_trap(0, static_cast(traits::RV_CAUSE_ILLEGAL_INSTRUCTION)); @@ -1660,11 +1709,13 @@ private: } bb->setName(fmt::format("SLLI_0x{:X}",pc.val)); this->gen_sync(PRE_SYNC,24); - auto cur_pc_val = this->gen_const(32,pc.val); + + this->gen_set_pc(pc, traits::PC); + this->set_tval(instr); pc=pc+ 4; this->gen_set_pc(pc, traits::NEXT_PC); - this->set_tval(instr); - + + this->gen_instr_prologue(); /*generate behavior*/ if(rd>=static_cast(traits::RFS)||rs1>=static_cast(traits::RFS)) { this->gen_raise_trap(0, static_cast(traits::RV_CAUSE_ILLEGAL_INSTRUCTION)); @@ -1708,11 +1759,13 @@ private: } bb->setName(fmt::format("SRLI_0x{:X}",pc.val)); this->gen_sync(PRE_SYNC,25); - auto cur_pc_val = this->gen_const(32,pc.val); + + this->gen_set_pc(pc, traits::PC); + this->set_tval(instr); pc=pc+ 4; this->gen_set_pc(pc, traits::NEXT_PC); - this->set_tval(instr); - + + this->gen_instr_prologue(); /*generate behavior*/ if(rd>=static_cast(traits::RFS)||rs1>=static_cast(traits::RFS)) { this->gen_raise_trap(0, static_cast(traits::RV_CAUSE_ILLEGAL_INSTRUCTION)); @@ -1756,11 +1809,13 @@ private: } bb->setName(fmt::format("SRAI_0x{:X}",pc.val)); this->gen_sync(PRE_SYNC,26); - auto cur_pc_val = this->gen_const(32,pc.val); + + this->gen_set_pc(pc, traits::PC); + this->set_tval(instr); pc=pc+ 4; this->gen_set_pc(pc, traits::NEXT_PC); - this->set_tval(instr); - + + this->gen_instr_prologue(); /*generate behavior*/ if(rd>=static_cast(traits::RFS)||rs1>=static_cast(traits::RFS)) { this->gen_raise_trap(0, static_cast(traits::RV_CAUSE_ILLEGAL_INSTRUCTION)); @@ -1806,11 +1861,13 @@ private: } bb->setName(fmt::format("ADD_0x{:X}",pc.val)); this->gen_sync(PRE_SYNC,27); - auto cur_pc_val = this->gen_const(32,pc.val); + + this->gen_set_pc(pc, traits::PC); + this->set_tval(instr); pc=pc+ 4; this->gen_set_pc(pc, traits::NEXT_PC); - this->set_tval(instr); - + + this->gen_instr_prologue(); /*generate behavior*/ if(rd>=static_cast(traits::RFS)||rs1>=static_cast(traits::RFS)||rs2>=static_cast(traits::RFS)) { this->gen_raise_trap(0, static_cast(traits::RV_CAUSE_ILLEGAL_INSTRUCTION)); @@ -1856,11 +1913,13 @@ private: } bb->setName(fmt::format("SUB_0x{:X}",pc.val)); this->gen_sync(PRE_SYNC,28); - auto cur_pc_val = this->gen_const(32,pc.val); + + this->gen_set_pc(pc, traits::PC); + this->set_tval(instr); pc=pc+ 4; this->gen_set_pc(pc, traits::NEXT_PC); - this->set_tval(instr); - + + this->gen_instr_prologue(); /*generate behavior*/ if(rd>=static_cast(traits::RFS)||rs1>=static_cast(traits::RFS)||rs2>=static_cast(traits::RFS)) { this->gen_raise_trap(0, static_cast(traits::RV_CAUSE_ILLEGAL_INSTRUCTION)); @@ -1906,11 +1965,13 @@ private: } bb->setName(fmt::format("SLL_0x{:X}",pc.val)); this->gen_sync(PRE_SYNC,29); - auto cur_pc_val = this->gen_const(32,pc.val); + + this->gen_set_pc(pc, traits::PC); + this->set_tval(instr); pc=pc+ 4; this->gen_set_pc(pc, traits::NEXT_PC); - this->set_tval(instr); - + + this->gen_instr_prologue(); /*generate behavior*/ if(rd>=static_cast(traits::RFS)||rs1>=static_cast(traits::RFS)||rs2>=static_cast(traits::RFS)) { this->gen_raise_trap(0, static_cast(traits::RV_CAUSE_ILLEGAL_INSTRUCTION)); @@ -1957,11 +2018,13 @@ private: } bb->setName(fmt::format("SLT_0x{:X}",pc.val)); this->gen_sync(PRE_SYNC,30); - auto cur_pc_val = this->gen_const(32,pc.val); + + this->gen_set_pc(pc, traits::PC); + this->set_tval(instr); pc=pc+ 4; this->gen_set_pc(pc, traits::NEXT_PC); - this->set_tval(instr); - + + this->gen_instr_prologue(); /*generate behavior*/ if(rd>=static_cast(traits::RFS)||rs1>=static_cast(traits::RFS)||rs2>=static_cast(traits::RFS)) { this->gen_raise_trap(0, static_cast(traits::RV_CAUSE_ILLEGAL_INSTRUCTION)); @@ -2010,11 +2073,13 @@ private: } bb->setName(fmt::format("SLTU_0x{:X}",pc.val)); this->gen_sync(PRE_SYNC,31); - auto cur_pc_val = this->gen_const(32,pc.val); + + this->gen_set_pc(pc, traits::PC); + this->set_tval(instr); pc=pc+ 4; this->gen_set_pc(pc, traits::NEXT_PC); - this->set_tval(instr); - + + this->gen_instr_prologue(); /*generate behavior*/ if(rd>=static_cast(traits::RFS)||rs1>=static_cast(traits::RFS)||rs2>=static_cast(traits::RFS)) { this->gen_raise_trap(0, static_cast(traits::RV_CAUSE_ILLEGAL_INSTRUCTION)); @@ -2061,11 +2126,13 @@ private: } bb->setName(fmt::format("XOR_0x{:X}",pc.val)); this->gen_sync(PRE_SYNC,32); - auto cur_pc_val = this->gen_const(32,pc.val); + + this->gen_set_pc(pc, traits::PC); + this->set_tval(instr); pc=pc+ 4; this->gen_set_pc(pc, traits::NEXT_PC); - this->set_tval(instr); - + + this->gen_instr_prologue(); /*generate behavior*/ if(rd>=static_cast(traits::RFS)||rs1>=static_cast(traits::RFS)||rs2>=static_cast(traits::RFS)) { this->gen_raise_trap(0, static_cast(traits::RV_CAUSE_ILLEGAL_INSTRUCTION)); @@ -2109,11 +2176,13 @@ private: } bb->setName(fmt::format("SRL_0x{:X}",pc.val)); this->gen_sync(PRE_SYNC,33); - auto cur_pc_val = this->gen_const(32,pc.val); + + this->gen_set_pc(pc, traits::PC); + this->set_tval(instr); pc=pc+ 4; this->gen_set_pc(pc, traits::NEXT_PC); - this->set_tval(instr); - + + this->gen_instr_prologue(); /*generate behavior*/ if(rd>=static_cast(traits::RFS)||rs1>=static_cast(traits::RFS)||rs2>=static_cast(traits::RFS)) { this->gen_raise_trap(0, static_cast(traits::RV_CAUSE_ILLEGAL_INSTRUCTION)); @@ -2160,11 +2229,13 @@ private: } bb->setName(fmt::format("SRA_0x{:X}",pc.val)); this->gen_sync(PRE_SYNC,34); - auto cur_pc_val = this->gen_const(32,pc.val); + + this->gen_set_pc(pc, traits::PC); + this->set_tval(instr); pc=pc+ 4; this->gen_set_pc(pc, traits::NEXT_PC); - this->set_tval(instr); - + + this->gen_instr_prologue(); /*generate behavior*/ if(rd>=static_cast(traits::RFS)||rs1>=static_cast(traits::RFS)||rs2>=static_cast(traits::RFS)) { this->gen_raise_trap(0, static_cast(traits::RV_CAUSE_ILLEGAL_INSTRUCTION)); @@ -2214,11 +2285,13 @@ private: } bb->setName(fmt::format("OR_0x{:X}",pc.val)); this->gen_sync(PRE_SYNC,35); - auto cur_pc_val = this->gen_const(32,pc.val); + + this->gen_set_pc(pc, traits::PC); + this->set_tval(instr); pc=pc+ 4; this->gen_set_pc(pc, traits::NEXT_PC); - this->set_tval(instr); - + + this->gen_instr_prologue(); /*generate behavior*/ if(rd>=static_cast(traits::RFS)||rs1>=static_cast(traits::RFS)||rs2>=static_cast(traits::RFS)) { this->gen_raise_trap(0, static_cast(traits::RV_CAUSE_ILLEGAL_INSTRUCTION)); @@ -2262,11 +2335,13 @@ private: } bb->setName(fmt::format("AND_0x{:X}",pc.val)); this->gen_sync(PRE_SYNC,36); - auto cur_pc_val = this->gen_const(32,pc.val); + + this->gen_set_pc(pc, traits::PC); + this->set_tval(instr); pc=pc+ 4; this->gen_set_pc(pc, traits::NEXT_PC); - this->set_tval(instr); - + + this->gen_instr_prologue(); /*generate behavior*/ if(rd>=static_cast(traits::RFS)||rs1>=static_cast(traits::RFS)||rs2>=static_cast(traits::RFS)) { this->gen_raise_trap(0, static_cast(traits::RV_CAUSE_ILLEGAL_INSTRUCTION)); @@ -2312,11 +2387,13 @@ private: } bb->setName(fmt::format("FENCE_0x{:X}",pc.val)); this->gen_sync(PRE_SYNC,37); - auto cur_pc_val = this->gen_const(32,pc.val); + + this->gen_set_pc(pc, traits::PC); + this->set_tval(instr); pc=pc+ 4; this->gen_set_pc(pc, traits::NEXT_PC); - this->set_tval(instr); - + + this->gen_instr_prologue(); /*generate behavior*/ this->gen_write_mem(traits::FENCE, static_cast(traits::fence), @@ -2336,14 +2413,23 @@ private: if(this->disass_enabled){ /* generate console output when executing the command */ //This disass is not yet implemented + std::string mnemonic = "ecall"; + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } bb->setName(fmt::format("ECALL_0x{:X}",pc.val)); this->gen_sync(PRE_SYNC,38); - auto cur_pc_val = this->gen_const(32,pc.val); + + this->gen_set_pc(pc, traits::PC); + this->set_tval(instr); pc=pc+ 4; this->gen_set_pc(pc, traits::NEXT_PC); - this->set_tval(instr); - + + this->gen_instr_prologue(); /*generate behavior*/ this->gen_raise_trap(0, 11); bb = this->leave_blk; @@ -2361,14 +2447,23 @@ private: if(this->disass_enabled){ /* generate console output when executing the command */ //This disass is not yet implemented + std::string mnemonic = "ebreak"; + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } bb->setName(fmt::format("EBREAK_0x{:X}",pc.val)); this->gen_sync(PRE_SYNC,39); - auto cur_pc_val = this->gen_const(32,pc.val); + + this->gen_set_pc(pc, traits::PC); + this->set_tval(instr); pc=pc+ 4; this->gen_set_pc(pc, traits::NEXT_PC); - this->set_tval(instr); - + + this->gen_instr_prologue(); /*generate behavior*/ this->gen_raise_trap(0, 3); bb = this->leave_blk; @@ -2386,14 +2481,23 @@ private: if(this->disass_enabled){ /* generate console output when executing the command */ //This disass is not yet implemented + std::string mnemonic = "mret"; + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } bb->setName(fmt::format("MRET_0x{:X}",pc.val)); this->gen_sync(PRE_SYNC,40); - auto cur_pc_val = this->gen_const(32,pc.val); + + this->gen_set_pc(pc, traits::PC); + this->set_tval(instr); pc=pc+ 4; this->gen_set_pc(pc, traits::NEXT_PC); - this->set_tval(instr); - + + this->gen_instr_prologue(); /*generate behavior*/ this->gen_leave_trap(3); bb = this->leave_blk; @@ -2411,14 +2515,23 @@ private: if(this->disass_enabled){ /* generate console output when executing the command */ //This disass is not yet implemented + std::string mnemonic = "wfi"; + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } bb->setName(fmt::format("WFI_0x{:X}",pc.val)); this->gen_sync(PRE_SYNC,41); - auto cur_pc_val = this->gen_const(32,pc.val); + + this->gen_set_pc(pc, traits::PC); + this->set_tval(instr); pc=pc+ 4; this->gen_set_pc(pc, traits::NEXT_PC); - this->set_tval(instr); - + + this->gen_instr_prologue(); /*generate behavior*/ this->gen_wait(1); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); @@ -2450,11 +2563,13 @@ private: } bb->setName(fmt::format("CSRRW_0x{:X}",pc.val)); this->gen_sync(PRE_SYNC,42); - auto cur_pc_val = this->gen_const(32,pc.val); + + this->gen_set_pc(pc, traits::PC); + this->set_tval(instr); pc=pc+ 4; this->gen_set_pc(pc, traits::NEXT_PC); - this->set_tval(instr); - + + this->gen_instr_prologue(); /*generate behavior*/ if(rd>=static_cast(traits::RFS)||rs1>=static_cast(traits::RFS)) { this->gen_raise_trap(0, static_cast(traits::RV_CAUSE_ILLEGAL_INSTRUCTION)); @@ -2504,11 +2619,13 @@ private: } bb->setName(fmt::format("CSRRS_0x{:X}",pc.val)); this->gen_sync(PRE_SYNC,43); - auto cur_pc_val = this->gen_const(32,pc.val); + + this->gen_set_pc(pc, traits::PC); + this->set_tval(instr); pc=pc+ 4; this->gen_set_pc(pc, traits::NEXT_PC); - this->set_tval(instr); - + + this->gen_instr_prologue(); /*generate behavior*/ if(rd>=static_cast(traits::RFS)||rs1>=static_cast(traits::RFS)) { this->gen_raise_trap(0, static_cast(traits::RV_CAUSE_ILLEGAL_INSTRUCTION)); @@ -2559,11 +2676,13 @@ private: } bb->setName(fmt::format("CSRRC_0x{:X}",pc.val)); this->gen_sync(PRE_SYNC,44); - auto cur_pc_val = this->gen_const(32,pc.val); + + this->gen_set_pc(pc, traits::PC); + this->set_tval(instr); pc=pc+ 4; this->gen_set_pc(pc, traits::NEXT_PC); - this->set_tval(instr); - + + this->gen_instr_prologue(); /*generate behavior*/ if(rd>=static_cast(traits::RFS)||rs1>=static_cast(traits::RFS)) { this->gen_raise_trap(0, static_cast(traits::RV_CAUSE_ILLEGAL_INSTRUCTION)); @@ -2614,11 +2733,13 @@ private: } bb->setName(fmt::format("CSRRWI_0x{:X}",pc.val)); this->gen_sync(PRE_SYNC,45); - auto cur_pc_val = this->gen_const(32,pc.val); + + this->gen_set_pc(pc, traits::PC); + this->set_tval(instr); pc=pc+ 4; this->gen_set_pc(pc, traits::NEXT_PC); - this->set_tval(instr); - + + this->gen_instr_prologue(); /*generate behavior*/ if(rd>=static_cast(traits::RFS)) { this->gen_raise_trap(0, static_cast(traits::RV_CAUSE_ILLEGAL_INSTRUCTION)); @@ -2663,11 +2784,13 @@ private: } bb->setName(fmt::format("CSRRSI_0x{:X}",pc.val)); this->gen_sync(PRE_SYNC,46); - auto cur_pc_val = this->gen_const(32,pc.val); + + this->gen_set_pc(pc, traits::PC); + this->set_tval(instr); pc=pc+ 4; this->gen_set_pc(pc, traits::NEXT_PC); - this->set_tval(instr); - + + this->gen_instr_prologue(); /*generate behavior*/ if(rd>=static_cast(traits::RFS)) { this->gen_raise_trap(0, static_cast(traits::RV_CAUSE_ILLEGAL_INSTRUCTION)); @@ -2717,11 +2840,13 @@ private: } bb->setName(fmt::format("CSRRCI_0x{:X}",pc.val)); this->gen_sync(PRE_SYNC,47); - auto cur_pc_val = this->gen_const(32,pc.val); + + this->gen_set_pc(pc, traits::PC); + this->set_tval(instr); pc=pc+ 4; this->gen_set_pc(pc, traits::NEXT_PC); - this->set_tval(instr); - + + this->gen_instr_prologue(); /*generate behavior*/ if(rd>=static_cast(traits::RFS)) { this->gen_raise_trap(0, static_cast(traits::RV_CAUSE_ILLEGAL_INSTRUCTION)); @@ -2771,11 +2896,13 @@ private: } bb->setName(fmt::format("FENCE_I_0x{:X}",pc.val)); this->gen_sync(PRE_SYNC,48); - auto cur_pc_val = this->gen_const(32,pc.val); + + this->gen_set_pc(pc, traits::PC); + this->set_tval(instr); pc=pc+ 4; this->gen_set_pc(pc, traits::NEXT_PC); - this->set_tval(instr); - + + this->gen_instr_prologue(); /*generate behavior*/ this->gen_write_mem(traits::FENCE, static_cast(traits::fencei), @@ -2809,11 +2936,13 @@ private: } bb->setName(fmt::format("MUL_0x{:X}",pc.val)); this->gen_sync(PRE_SYNC,49); - auto cur_pc_val = this->gen_const(32,pc.val); + + this->gen_set_pc(pc, traits::PC); + this->set_tval(instr); pc=pc+ 4; this->gen_set_pc(pc, traits::NEXT_PC); - this->set_tval(instr); - + + this->gen_instr_prologue(); /*generate behavior*/ if(rd>=static_cast(traits::RFS)||rs1>=static_cast(traits::RFS)||rs2>=static_cast(traits::RFS)) { this->gen_raise_trap(0, static_cast(traits::RV_CAUSE_ILLEGAL_INSTRUCTION)); @@ -2862,11 +2991,13 @@ private: } bb->setName(fmt::format("MULH_0x{:X}",pc.val)); this->gen_sync(PRE_SYNC,50); - auto cur_pc_val = this->gen_const(32,pc.val); + + this->gen_set_pc(pc, traits::PC); + this->set_tval(instr); pc=pc+ 4; this->gen_set_pc(pc, traits::NEXT_PC); - this->set_tval(instr); - + + this->gen_instr_prologue(); /*generate behavior*/ if(rd>=static_cast(traits::RFS)||rs1>=static_cast(traits::RFS)||rs2>=static_cast(traits::RFS)) { this->gen_raise_trap(0, static_cast(traits::RV_CAUSE_ILLEGAL_INSTRUCTION)); @@ -2918,11 +3049,13 @@ private: } bb->setName(fmt::format("MULHSU_0x{:X}",pc.val)); this->gen_sync(PRE_SYNC,51); - auto cur_pc_val = this->gen_const(32,pc.val); + + this->gen_set_pc(pc, traits::PC); + this->set_tval(instr); pc=pc+ 4; this->gen_set_pc(pc, traits::NEXT_PC); - this->set_tval(instr); - + + this->gen_instr_prologue(); /*generate behavior*/ if(rd>=static_cast(traits::RFS)||rs1>=static_cast(traits::RFS)||rs2>=static_cast(traits::RFS)) { this->gen_raise_trap(0, static_cast(traits::RV_CAUSE_ILLEGAL_INSTRUCTION)); @@ -2973,11 +3106,13 @@ private: } bb->setName(fmt::format("MULHU_0x{:X}",pc.val)); this->gen_sync(PRE_SYNC,52); - auto cur_pc_val = this->gen_const(32,pc.val); + + this->gen_set_pc(pc, traits::PC); + this->set_tval(instr); pc=pc+ 4; this->gen_set_pc(pc, traits::NEXT_PC); - this->set_tval(instr); - + + this->gen_instr_prologue(); /*generate behavior*/ if(rd>=static_cast(traits::RFS)||rs1>=static_cast(traits::RFS)||rs2>=static_cast(traits::RFS)) { this->gen_raise_trap(0, static_cast(traits::RV_CAUSE_ILLEGAL_INSTRUCTION)); @@ -3027,11 +3162,13 @@ private: } bb->setName(fmt::format("DIV_0x{:X}",pc.val)); this->gen_sync(PRE_SYNC,53); - auto cur_pc_val = this->gen_const(32,pc.val); + + this->gen_set_pc(pc, traits::PC); + this->set_tval(instr); pc=pc+ 4; this->gen_set_pc(pc, traits::NEXT_PC); - this->set_tval(instr); - + + this->gen_instr_prologue(); /*generate behavior*/ if(rd>=static_cast(traits::RFS)||rs1>=static_cast(traits::RFS)||rs2>=static_cast(traits::RFS)) { this->gen_raise_trap(0, static_cast(traits::RV_CAUSE_ILLEGAL_INSTRUCTION)); @@ -3125,11 +3262,13 @@ private: } bb->setName(fmt::format("DIVU_0x{:X}",pc.val)); this->gen_sync(PRE_SYNC,54); - auto cur_pc_val = this->gen_const(32,pc.val); + + this->gen_set_pc(pc, traits::PC); + this->set_tval(instr); pc=pc+ 4; this->gen_set_pc(pc, traits::NEXT_PC); - this->set_tval(instr); - + + this->gen_instr_prologue(); /*generate behavior*/ if(rd>=static_cast(traits::RFS)||rs1>=static_cast(traits::RFS)||rs2>=static_cast(traits::RFS)) { this->gen_raise_trap(0, static_cast(traits::RV_CAUSE_ILLEGAL_INSTRUCTION)); @@ -3194,11 +3333,13 @@ private: } bb->setName(fmt::format("REM_0x{:X}",pc.val)); this->gen_sync(PRE_SYNC,55); - auto cur_pc_val = this->gen_const(32,pc.val); + + this->gen_set_pc(pc, traits::PC); + this->set_tval(instr); pc=pc+ 4; this->gen_set_pc(pc, traits::NEXT_PC); - this->set_tval(instr); - + + this->gen_instr_prologue(); /*generate behavior*/ if(rd>=static_cast(traits::RFS)||rs1>=static_cast(traits::RFS)||rs2>=static_cast(traits::RFS)) { this->gen_raise_trap(0, static_cast(traits::RV_CAUSE_ILLEGAL_INSTRUCTION)); @@ -3296,11 +3437,13 @@ private: } bb->setName(fmt::format("REMU_0x{:X}",pc.val)); this->gen_sync(PRE_SYNC,56); - auto cur_pc_val = this->gen_const(32,pc.val); + + this->gen_set_pc(pc, traits::PC); + this->set_tval(instr); pc=pc+ 4; this->gen_set_pc(pc, traits::NEXT_PC); - this->set_tval(instr); - + + this->gen_instr_prologue(); /*generate behavior*/ if(rd>=static_cast(traits::RFS)||rs1>=static_cast(traits::RFS)||rs2>=static_cast(traits::RFS)) { this->gen_raise_trap(0, static_cast(traits::RV_CAUSE_ILLEGAL_INSTRUCTION)); @@ -3364,11 +3507,13 @@ private: } bb->setName(fmt::format("C__ADDI4SPN_0x{:X}",pc.val)); this->gen_sync(PRE_SYNC,57); - auto cur_pc_val = this->gen_const(32,pc.val); + + this->gen_set_pc(pc, traits::PC); + this->set_tval(instr); pc=pc+ 2; this->gen_set_pc(pc, traits::NEXT_PC); - this->set_tval(instr); - + + this->gen_instr_prologue(); /*generate behavior*/ if(imm) { this->builder.CreateStore( @@ -3412,11 +3557,13 @@ private: } bb->setName(fmt::format("C__LW_0x{:X}",pc.val)); this->gen_sync(PRE_SYNC,58); - auto cur_pc_val = this->gen_const(32,pc.val); + + this->gen_set_pc(pc, traits::PC); + this->set_tval(instr); pc=pc+ 2; this->gen_set_pc(pc, traits::NEXT_PC); - this->set_tval(instr); - + + this->gen_instr_prologue(); /*generate behavior*/ auto offs =this->gen_ext( (this->builder.CreateAdd( @@ -3460,11 +3607,13 @@ private: } bb->setName(fmt::format("C__SW_0x{:X}",pc.val)); this->gen_sync(PRE_SYNC,59); - auto cur_pc_val = this->gen_const(32,pc.val); + + this->gen_set_pc(pc, traits::PC); + this->set_tval(instr); pc=pc+ 2; this->gen_set_pc(pc, traits::NEXT_PC); - this->set_tval(instr); - + + this->gen_instr_prologue(); /*generate behavior*/ auto offs =this->gen_ext( (this->builder.CreateAdd( @@ -3505,11 +3654,13 @@ private: } bb->setName(fmt::format("C__ADDI_0x{:X}",pc.val)); this->gen_sync(PRE_SYNC,60); - auto cur_pc_val = this->gen_const(32,pc.val); + + this->gen_set_pc(pc, traits::PC); + this->set_tval(instr); pc=pc+ 2; this->gen_set_pc(pc, traits::NEXT_PC); - this->set_tval(instr); - + + this->gen_instr_prologue(); /*generate behavior*/ if(rs1>=static_cast(traits::RFS)) { this->gen_raise_trap(0, static_cast(traits::RV_CAUSE_ILLEGAL_INSTRUCTION)); @@ -3542,14 +3693,23 @@ private: if(this->disass_enabled){ /* generate console output when executing the command */ //This disass is not yet implemented + std::string mnemonic = "c__nop"; + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } bb->setName(fmt::format("C__NOP_0x{:X}",pc.val)); this->gen_sync(PRE_SYNC,61); - auto cur_pc_val = this->gen_const(32,pc.val); + + this->gen_set_pc(pc, traits::PC); + this->set_tval(instr); pc=pc+ 2; this->gen_set_pc(pc, traits::NEXT_PC); - this->set_tval(instr); - + + this->gen_instr_prologue(); /*generate behavior*/ bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); auto returnValue = std::make_tuple(CONT,bb); @@ -3578,11 +3738,13 @@ private: } bb->setName(fmt::format("C__JAL_0x{:X}",pc.val)); this->gen_sync(PRE_SYNC,62); - auto cur_pc_val = this->gen_const(32,pc.val); + + this->gen_set_pc(pc, traits::PC); + this->set_tval(instr); pc=pc+ 2; this->gen_set_pc(pc, traits::NEXT_PC); - this->set_tval(instr); - + + this->gen_instr_prologue(); /*generate behavior*/ this->builder.CreateStore( this->gen_const(32,(uint32_t)(PC+2)), @@ -3618,11 +3780,13 @@ private: } bb->setName(fmt::format("C__LI_0x{:X}",pc.val)); this->gen_sync(PRE_SYNC,63); - auto cur_pc_val = this->gen_const(32,pc.val); + + this->gen_set_pc(pc, traits::PC); + this->set_tval(instr); pc=pc+ 2; this->gen_set_pc(pc, traits::NEXT_PC); - this->set_tval(instr); - + + this->gen_instr_prologue(); /*generate behavior*/ if(rd>=static_cast(traits::RFS)) { this->gen_raise_trap(0, static_cast(traits::RV_CAUSE_ILLEGAL_INSTRUCTION)); @@ -3662,11 +3826,13 @@ private: } bb->setName(fmt::format("C__LUI_0x{:X}",pc.val)); this->gen_sync(PRE_SYNC,64); - auto cur_pc_val = this->gen_const(32,pc.val); + + this->gen_set_pc(pc, traits::PC); + this->set_tval(instr); pc=pc+ 2; this->gen_set_pc(pc, traits::NEXT_PC); - this->set_tval(instr); - + + this->gen_instr_prologue(); /*generate behavior*/ if(imm==0||rd>=static_cast(traits::RFS)) { this->gen_raise_trap(0, static_cast(traits::RV_CAUSE_ILLEGAL_INSTRUCTION)); @@ -3703,11 +3869,13 @@ private: } bb->setName(fmt::format("C__ADDI16SP_0x{:X}",pc.val)); this->gen_sync(PRE_SYNC,65); - auto cur_pc_val = this->gen_const(32,pc.val); + + this->gen_set_pc(pc, traits::PC); + this->set_tval(instr); pc=pc+ 2; this->gen_set_pc(pc, traits::NEXT_PC); - this->set_tval(instr); - + + this->gen_instr_prologue(); /*generate behavior*/ if(nzimm) { this->builder.CreateStore( @@ -3738,14 +3906,23 @@ private: if(this->disass_enabled){ /* generate console output when executing the command */ //This disass is not yet implemented + std::string mnemonic = "__reserved_clui"; + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } bb->setName(fmt::format("__reserved_clui_0x{:X}",pc.val)); this->gen_sync(PRE_SYNC,66); - auto cur_pc_val = this->gen_const(32,pc.val); + + this->gen_set_pc(pc, traits::PC); + this->set_tval(instr); pc=pc+ 2; this->gen_set_pc(pc, traits::NEXT_PC); - this->set_tval(instr); - + + this->gen_instr_prologue(); /*generate behavior*/ this->gen_raise_trap(0, static_cast(traits::RV_CAUSE_ILLEGAL_INSTRUCTION)); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); @@ -3776,11 +3953,13 @@ private: } bb->setName(fmt::format("C__SRLI_0x{:X}",pc.val)); this->gen_sync(PRE_SYNC,67); - auto cur_pc_val = this->gen_const(32,pc.val); + + this->gen_set_pc(pc, traits::PC); + this->set_tval(instr); pc=pc+ 2; this->gen_set_pc(pc, traits::NEXT_PC); - this->set_tval(instr); - + + this->gen_instr_prologue(); /*generate behavior*/ this->builder.CreateStore( this->builder.CreateLShr( @@ -3816,11 +3995,13 @@ private: } bb->setName(fmt::format("C__SRAI_0x{:X}",pc.val)); this->gen_sync(PRE_SYNC,68); - auto cur_pc_val = this->gen_const(32,pc.val); + + this->gen_set_pc(pc, traits::PC); + this->set_tval(instr); pc=pc+ 2; this->gen_set_pc(pc, traits::NEXT_PC); - this->set_tval(instr); - + + this->gen_instr_prologue(); /*generate behavior*/ if(shamt){ this->builder.CreateStore( this->gen_ext( @@ -3874,11 +4055,13 @@ private: } bb->setName(fmt::format("C__ANDI_0x{:X}",pc.val)); this->gen_sync(PRE_SYNC,69); - auto cur_pc_val = this->gen_const(32,pc.val); + + this->gen_set_pc(pc, traits::PC); + this->set_tval(instr); pc=pc+ 2; this->gen_set_pc(pc, traits::NEXT_PC); - this->set_tval(instr); - + + this->gen_instr_prologue(); /*generate behavior*/ this->builder.CreateStore( this->gen_ext( @@ -3916,11 +4099,13 @@ private: } bb->setName(fmt::format("C__SUB_0x{:X}",pc.val)); this->gen_sync(PRE_SYNC,70); - auto cur_pc_val = this->gen_const(32,pc.val); + + this->gen_set_pc(pc, traits::PC); + this->set_tval(instr); pc=pc+ 2; this->gen_set_pc(pc, traits::NEXT_PC); - this->set_tval(instr); - + + this->gen_instr_prologue(); /*generate behavior*/ this->builder.CreateStore( this->gen_ext( @@ -3958,11 +4143,13 @@ private: } bb->setName(fmt::format("C__XOR_0x{:X}",pc.val)); this->gen_sync(PRE_SYNC,71); - auto cur_pc_val = this->gen_const(32,pc.val); + + this->gen_set_pc(pc, traits::PC); + this->set_tval(instr); pc=pc+ 2; this->gen_set_pc(pc, traits::NEXT_PC); - this->set_tval(instr); - + + this->gen_instr_prologue(); /*generate behavior*/ this->builder.CreateStore( this->builder.CreateXor( @@ -3998,11 +4185,13 @@ private: } bb->setName(fmt::format("C__OR_0x{:X}",pc.val)); this->gen_sync(PRE_SYNC,72); - auto cur_pc_val = this->gen_const(32,pc.val); + + this->gen_set_pc(pc, traits::PC); + this->set_tval(instr); pc=pc+ 2; this->gen_set_pc(pc, traits::NEXT_PC); - this->set_tval(instr); - + + this->gen_instr_prologue(); /*generate behavior*/ this->builder.CreateStore( this->builder.CreateOr( @@ -4038,11 +4227,13 @@ private: } bb->setName(fmt::format("C__AND_0x{:X}",pc.val)); this->gen_sync(PRE_SYNC,73); - auto cur_pc_val = this->gen_const(32,pc.val); + + this->gen_set_pc(pc, traits::PC); + this->set_tval(instr); pc=pc+ 2; this->gen_set_pc(pc, traits::NEXT_PC); - this->set_tval(instr); - + + this->gen_instr_prologue(); /*generate behavior*/ this->builder.CreateStore( this->builder.CreateAnd( @@ -4077,11 +4268,13 @@ private: } bb->setName(fmt::format("C__J_0x{:X}",pc.val)); this->gen_sync(PRE_SYNC,74); - auto cur_pc_val = this->gen_const(32,pc.val); + + this->gen_set_pc(pc, traits::PC); + this->set_tval(instr); pc=pc+ 2; this->gen_set_pc(pc, traits::NEXT_PC); - this->set_tval(instr); - + + this->gen_instr_prologue(); /*generate behavior*/ 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); @@ -4114,11 +4307,13 @@ private: } bb->setName(fmt::format("C__BEQZ_0x{:X}",pc.val)); this->gen_sync(PRE_SYNC,75); - auto cur_pc_val = this->gen_const(32,pc.val); + + this->gen_set_pc(pc, traits::PC); + this->set_tval(instr); pc=pc+ 2; this->gen_set_pc(pc, traits::NEXT_PC); - this->set_tval(instr); - + + this->gen_instr_prologue(); /*generate behavior*/ 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); @@ -4162,11 +4357,13 @@ private: } bb->setName(fmt::format("C__BNEZ_0x{:X}",pc.val)); this->gen_sync(PRE_SYNC,76); - auto cur_pc_val = this->gen_const(32,pc.val); + + this->gen_set_pc(pc, traits::PC); + this->set_tval(instr); pc=pc+ 2; this->gen_set_pc(pc, traits::NEXT_PC); - this->set_tval(instr); - + + this->gen_instr_prologue(); /*generate behavior*/ 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); @@ -4210,11 +4407,13 @@ private: } bb->setName(fmt::format("C__SLLI_0x{:X}",pc.val)); this->gen_sync(PRE_SYNC,77); - auto cur_pc_val = this->gen_const(32,pc.val); + + this->gen_set_pc(pc, traits::PC); + this->set_tval(instr); pc=pc+ 2; this->gen_set_pc(pc, traits::NEXT_PC); - this->set_tval(instr); - + + this->gen_instr_prologue(); /*generate behavior*/ if(rs1>=static_cast(traits::RFS)) { this->gen_raise_trap(0, static_cast(traits::RV_CAUSE_ILLEGAL_INSTRUCTION)); @@ -4257,11 +4456,13 @@ private: } bb->setName(fmt::format("C__LWSP_0x{:X}",pc.val)); this->gen_sync(PRE_SYNC,78); - auto cur_pc_val = this->gen_const(32,pc.val); + + this->gen_set_pc(pc, traits::PC); + this->set_tval(instr); pc=pc+ 2; this->gen_set_pc(pc, traits::NEXT_PC); - this->set_tval(instr); - + + this->gen_instr_prologue(); /*generate behavior*/ if(rd>=static_cast(traits::RFS)||rd==0) { this->gen_raise_trap(0, static_cast(traits::RV_CAUSE_ILLEGAL_INSTRUCTION)); @@ -4309,11 +4510,13 @@ private: } bb->setName(fmt::format("C__MV_0x{:X}",pc.val)); this->gen_sync(PRE_SYNC,79); - auto cur_pc_val = this->gen_const(32,pc.val); + + this->gen_set_pc(pc, traits::PC); + this->set_tval(instr); pc=pc+ 2; this->gen_set_pc(pc, traits::NEXT_PC); - this->set_tval(instr); - + + this->gen_instr_prologue(); /*generate behavior*/ if(rd>=static_cast(traits::RFS)) { this->gen_raise_trap(0, static_cast(traits::RV_CAUSE_ILLEGAL_INSTRUCTION)); @@ -4352,11 +4555,13 @@ private: } bb->setName(fmt::format("C__JR_0x{:X}",pc.val)); this->gen_sync(PRE_SYNC,80); - auto cur_pc_val = this->gen_const(32,pc.val); + + this->gen_set_pc(pc, traits::PC); + this->set_tval(instr); pc=pc+ 2; this->gen_set_pc(pc, traits::NEXT_PC); - this->set_tval(instr); - + + this->gen_instr_prologue(); /*generate behavior*/ if(rs1&&rs1(traits::RFS)){ auto addr_mask =(uint32_t)- 2; auto PC_val_v = this->builder.CreateAnd( @@ -4384,14 +4589,23 @@ private: if(this->disass_enabled){ /* generate console output when executing the command */ //This disass is not yet implemented + std::string mnemonic = "__reserved_cmv"; + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } bb->setName(fmt::format("__reserved_cmv_0x{:X}",pc.val)); this->gen_sync(PRE_SYNC,81); - auto cur_pc_val = this->gen_const(32,pc.val); + + this->gen_set_pc(pc, traits::PC); + this->set_tval(instr); pc=pc+ 2; this->gen_set_pc(pc, traits::NEXT_PC); - this->set_tval(instr); - + + this->gen_instr_prologue(); /*generate behavior*/ this->gen_raise_trap(0, 2); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); @@ -4422,11 +4636,13 @@ private: } bb->setName(fmt::format("C__ADD_0x{:X}",pc.val)); this->gen_sync(PRE_SYNC,82); - auto cur_pc_val = this->gen_const(32,pc.val); + + this->gen_set_pc(pc, traits::PC); + this->set_tval(instr); pc=pc+ 2; this->gen_set_pc(pc, traits::NEXT_PC); - this->set_tval(instr); - + + this->gen_instr_prologue(); /*generate behavior*/ if(rd>=static_cast(traits::RFS)) { this->gen_raise_trap(0, static_cast(traits::RV_CAUSE_ILLEGAL_INSTRUCTION)); @@ -4470,11 +4686,13 @@ private: } bb->setName(fmt::format("C__JALR_0x{:X}",pc.val)); this->gen_sync(PRE_SYNC,83); - auto cur_pc_val = this->gen_const(32,pc.val); + + this->gen_set_pc(pc, traits::PC); + this->set_tval(instr); pc=pc+ 2; this->gen_set_pc(pc, traits::NEXT_PC); - this->set_tval(instr); - + + this->gen_instr_prologue(); /*generate behavior*/ if(rs1>=static_cast(traits::RFS)) { this->gen_raise_trap(0, static_cast(traits::RV_CAUSE_ILLEGAL_INSTRUCTION)); @@ -4507,14 +4725,23 @@ private: if(this->disass_enabled){ /* generate console output when executing the command */ //This disass is not yet implemented + std::string mnemonic = "c__ebreak"; + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } bb->setName(fmt::format("C__EBREAK_0x{:X}",pc.val)); this->gen_sync(PRE_SYNC,84); - auto cur_pc_val = this->gen_const(32,pc.val); + + this->gen_set_pc(pc, traits::PC); + this->set_tval(instr); pc=pc+ 2; this->gen_set_pc(pc, traits::NEXT_PC); - this->set_tval(instr); - + + this->gen_instr_prologue(); /*generate behavior*/ this->gen_raise_trap(0, 3); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); @@ -4545,11 +4772,13 @@ private: } bb->setName(fmt::format("C__SWSP_0x{:X}",pc.val)); this->gen_sync(PRE_SYNC,85); - auto cur_pc_val = this->gen_const(32,pc.val); + + this->gen_set_pc(pc, traits::PC); + this->set_tval(instr); pc=pc+ 2; this->gen_set_pc(pc, traits::NEXT_PC); - this->set_tval(instr); - + + this->gen_instr_prologue(); /*generate behavior*/ if(rs2>=static_cast(traits::RFS)) { this->gen_raise_trap(0, static_cast(traits::RV_CAUSE_ILLEGAL_INSTRUCTION)); @@ -4582,14 +4811,23 @@ private: if(this->disass_enabled){ /* generate console output when executing the command */ //This disass is not yet implemented + std::string mnemonic = "dii"; + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } bb->setName(fmt::format("DII_0x{:X}",pc.val)); this->gen_sync(PRE_SYNC,86); - auto cur_pc_val = this->gen_const(32,pc.val); + + this->gen_set_pc(pc, traits::PC); + this->set_tval(instr); pc=pc+ 2; this->gen_set_pc(pc, traits::NEXT_PC); - this->set_tval(instr); - + + this->gen_instr_prologue(); /*generate behavior*/ this->gen_raise_trap(0, static_cast(traits::RV_CAUSE_ILLEGAL_INSTRUCTION)); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); @@ -4741,15 +4979,12 @@ template void vm_impl::gen_raise_trap(uint16_t trap_id, uint16_t cause) { auto *TRAP_val = this->gen_const(32, 0x80 << 24 | (cause << 16) | trap_id); this->builder.CreateStore(TRAP_val, get_reg_ptr(traits::TRAP_STATE), true); - this->builder.CreateStore(this->gen_const(32U, std::numeric_limits::max()), get_reg_ptr(traits::LAST_BRANCH), false); } template void vm_impl::gen_leave_trap(unsigned lvl) { std::vector args{ this->core_ptr, ConstantInt::get(getContext(), APInt(64, lvl)) }; this->builder.CreateCall(this->mod->getFunction("leave_trap"), args); - auto *PC_val = this->gen_read_mem(traits::CSR, (lvl << 8) + 0x41, traits::XLEN / 8); - this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); this->builder.CreateStore(this->gen_const(32U, std::numeric_limits::max()), get_reg_ptr(traits::LAST_BRANCH), false); } @@ -4772,14 +5007,24 @@ template void vm_impl::gen_trap_behavior(BasicBlock *trap_blk) { this->builder.SetInsertPoint(trap_blk); auto *trap_state_val = this->builder.CreateLoad(this->get_typeptr(traits::TRAP_STATE), get_reg_ptr(traits::TRAP_STATE), true); - this->builder.CreateStore(this->gen_const(32U, std::numeric_limits::max()), - get_reg_ptr(traits::LAST_BRANCH), false); - std::vector args{this->core_ptr, this->adj_to64(trap_state_val), + auto *cur_pc_val = this->builder.CreateLoad(this->get_typeptr(traits::PC), get_reg_ptr(traits::PC), true); + std::vector args{this->core_ptr, + this->adj_to64(trap_state_val), + this->adj_to64(cur_pc_val), this->adj_to64(this->builder.CreateLoad(this->get_type(64),this->tval))}; this->builder.CreateCall(this->mod->getFunction("enter_trap"), args); + this->builder.CreateStore(this->gen_const(32U, std::numeric_limits::max()), get_reg_ptr(traits::LAST_BRANCH), false); + auto *trap_addr_val = this->builder.CreateLoad(this->get_typeptr(traits::NEXT_PC), get_reg_ptr(traits::NEXT_PC), false); this->builder.CreateRet(trap_addr_val); } +template +void vm_impl::gen_instr_prologue() { + auto* trap_val = + this->builder.CreateLoad(this->get_typeptr(arch::traits::PENDING_TRAP), get_reg_ptr(arch::traits::PENDING_TRAP)); + this->builder.CreateStore(trap_val, get_reg_ptr(arch::traits::TRAP_STATE), false); +} + template void vm_impl::gen_instr_epilogue(BasicBlock *bb) { @@ -4790,6 +5035,10 @@ void vm_impl::gen_instr_epilogue(BasicBlock *bb) { ConstantInt::get(getContext(), APInt(v->getType()->getIntegerBitWidth(), 0))), target_bb, this->trap_blk, 1); this->builder.SetInsertPoint(target_bb); + // update icount + auto* icount_val = this->builder.CreateAdd( + this->builder.CreateLoad(this->get_typeptr(arch::traits::ICOUNT), get_reg_ptr(arch::traits::ICOUNT)), this->gen_const(64U, 1)); + this->builder.CreateStore(icount_val, get_reg_ptr(arch::traits::ICOUNT), false); } } // namespace tgc5c