Fixed handling of compressed ISA
This commit is contained in:
		
							
								
								
									
										2
									
								
								dbt-core
									
									
									
									
									
								
							
							
								
								
								
								
								
							
						
						
									
										2
									
								
								dbt-core
									
									
									
									
									
								
							 Submodule dbt-core updated: 55b281a010...29a69884d2
									
								
							| @@ -97,14 +97,14 @@ public: | ||||
|     void notify_phase(iss::arch_if::exec_phase phase); | ||||
|  | ||||
|     void disass_output(uint64_t pc, const std::string instr) override { | ||||
| #ifndef WITH_SCV | ||||
|         std::stringstream s; | ||||
|         s << "[p:" << lvl[this->reg.machine_state] << ";s:0x" << std::hex << std::setfill('0') | ||||
|           << std::setw(sizeof(reg_t) * 2) << (reg_t)state.mstatus << std::dec << ";c:" << this->reg.icount << "]"; | ||||
|         CLOG(INFO, disass) << "0x"<<std::setw(16)<<std::setfill('0')<<std::hex<<pc<<"\t\t"<<instr<<"\t"<<s.str(); | ||||
| #else | ||||
|     	if (logging::INFO <= logging::Log<logging::Output2FILE<logging::disass>>::reporting_level() && logging::Output2FILE<logging::disass>::stream()){ | ||||
| 			std::stringstream s; | ||||
| 			s << "[p:" << lvl[this->reg.machine_state] << ";s:0x" << std::hex << std::setfill('0') | ||||
| 			  << std::setw(sizeof(reg_t) * 2) << (reg_t)state.mstatus << std::dec << ";c:" << this->reg.icount << "]"; | ||||
| 			scc::Log<logging::Output2FILE<logging::disass>>().get(logging::INFO, "disass") | ||||
| 					<< "0x"<<std::setw(16)<<std::setfill('0')<<std::hex<<pc<<"\t\t"<<std::setw(40)<<std::setfill(' ')<<std::left<<instr<<s.str(); | ||||
|     	} | ||||
|         owner->disass_output(pc,instr); | ||||
| #endif | ||||
|     }; | ||||
|  | ||||
|     iss::status read_mem(phys_addr_t addr, unsigned length, uint8_t *const data) { | ||||
| @@ -221,7 +221,7 @@ void core_complex::start_of_simulation() { | ||||
|     quantum_keeper.reset(); | ||||
|     if (elf_file.value.size() > 0) cpu->load_file(elf_file.value); | ||||
| #ifdef WITH_SCV | ||||
|         if (stream_handle == NULL) { | ||||
|         if (m_db!=nullptr && stream_handle == nullptr) { | ||||
|             string basename(this->name()); | ||||
|             stream_handle = new scv_tr_stream((basename + ".instr").c_str(), "TRANSACTOR", m_db); | ||||
|             instr_tr_handle = new scv_tr_generator<>("execute", *stream_handle); | ||||
| @@ -232,6 +232,7 @@ void core_complex::start_of_simulation() { | ||||
|  | ||||
| void core_complex::disass_output(uint64_t pc, const std::string instr_str) { | ||||
| #ifdef WITH_SCV | ||||
| 	if (m_db==nullptr) return; | ||||
|     if(tr_handle.is_active()) tr_handle.end_transaction(); | ||||
|     tr_handle = instr_tr_handle->begin_transaction(); | ||||
|     tr_handle.record_attribute("PC", pc); | ||||
| @@ -270,7 +271,7 @@ bool core_complex::read_mem(uint64_t addr, unsigned length, uint8_t *const data, | ||||
|         gp.set_streaming_width(4); | ||||
|         auto delay{quantum_keeper.get_local_time()}; | ||||
| #ifdef WITH_SCV | ||||
|         if(tr_handle.is_valid()){ | ||||
|         if(m_db!=nullptr && tr_handle.is_valid()){ | ||||
|             if(is_fetch && tr_handle.is_active()) tr_handle.end_transaction(); | ||||
|             auto preExt = new scv4tlm::tlm_recording_extension(tr_handle, this); | ||||
|             gp.set_extension(preExt); | ||||
|   | ||||
| @@ -12,42 +12,37 @@ InsructionSet RV32CI { | ||||
| 				PC[XLEN](is_pc) | ||||
| 	} | ||||
| 	instructions{ | ||||
| 		C.ADDI4SPN { //(RES, nzuimm=0) | ||||
| 			encoding: b000 | nzuimm[5:4] | nzuimm[9:6] | nzuimm[2:2] | nzuimm[3:3] | rd[2:0] | b00; | ||||
| 			args_disass: "x%rd$d, 0x%nzuimm$05x"; | ||||
| 			if(nzuimm == 0) | ||||
| 				raise(0, 2); | ||||
| 		C.ADDI4SPN { //(RES, imm=0) | ||||
| 			encoding: b000 | imm[5:4] | imm[9:6] | imm[2:2] | imm[3:3] | rd[2:0] | b00; | ||||
| 			args_disass: "x%rd$d, 0x%imm$05x"; | ||||
| 			if(imm == 0) raise(0, 2); | ||||
| 			val rd_idx[5] <= rd+8; | ||||
| 			val x2_idx[5] <= 2; | ||||
| 			X[rd_idx] <= X[x2_idx] + nzuimm; | ||||
| 			X[rd_idx] <= X[x2_idx] + imm; | ||||
| 		} | ||||
| 		C.LW { // (RV32) | ||||
| 			encoding: b010 | uimm[5:3] | rs1[2:0] | uimm[2:2] | uimm[6:6] | rd[2:0] | b00; | ||||
| 			args_disass: "x(8+%rd$d), x(8+%rs1$d), 0x%uimm$05x"; | ||||
| 			val rs1_idx[5] <= rs1+8; | ||||
| 			val adr[XLEN] <= X[rs1_idx]+uimm; | ||||
| 			val rd_idx[5] <= rd+8; | ||||
| 			X[rd_idx] <= MEM[adr]{32}; | ||||
| 			val offs[XLEN] <= X[rs1_idx]+uimm; | ||||
| 			X[rd_idx] <= MEM[offs]{32}; | ||||
| 		} | ||||
| 		C.SW {//(RV32) | ||||
| 			encoding: b110 | uimm[5:3] | rs1[2:0] | uimm[2:2] | uimm[6:6] | rs2[2:0] | b00; | ||||
| 			args_disass: "x(8+%rs1$d), x(8+%rs2$d), 0x%uimm$05x"; | ||||
| 			val rs1_idx[5] <= rs1+8; | ||||
| 			val adr[XLEN] <= X[rs1_idx]+uimm; | ||||
| 			val rs2_idx[5] <= rs2+8; | ||||
| 			MEM[adr]{32} <= X[rs2_idx]; | ||||
| 		} | ||||
| 		C.NOP {//(RV32) | ||||
| 			encoding: b000 | b0 | b00000 | b00000 | b01; //TODO | ||||
| 			args_disass: ""; | ||||
| 			val offs[XLEN] <= X[rs1_idx]+uimm; | ||||
| 			MEM[offs]{32} <= X[rs2_idx]; | ||||
| 		} | ||||
| 		C.ADDI {//(RV32) | ||||
| 			encoding:b000 | nzimm[5:5]s | rs1[4:0] | nzimm[4:0]s | b01; | ||||
| 			args_disass: "x%rs1$d, 0x%nzimm$05x"; | ||||
| 			if(nzimm == 0) | ||||
| 				raise(0, 2); | ||||
| 			X[rs1] <= X[rs1] + nzimm; | ||||
| 			 | ||||
| 			encoding:b000 | imm[5:5]s | rs1[4:0] | imm[4:0]s | b01; | ||||
| 			args_disass: "x%rs1$d, 0x%imm$05x"; | ||||
| 			X[rs1] <= X[rs1] + imm; | ||||
| 		} | ||||
| 		C.NOP { | ||||
| 			encoding:b000 | b0 | b00000 | b00000 | b01; | ||||
| 		} | ||||
|         // C.JAL will be overwritten by C.ADDIW for RV64/128 | ||||
| 		C.JAL(no_cont) {//(RV32) | ||||
| @@ -60,35 +55,32 @@ InsructionSet RV32CI { | ||||
| 		C.LI {//(RV32) | ||||
| 			encoding:b010 | imm[5:5]s | rd[4:0] | imm[4:0]s | b01; | ||||
| 			args_disass: "x%rd$d, 0x%imm$05x"; | ||||
| 			if(rd == 0)	raise(0, 2); | ||||
| 			if(rd == 0)	raise(0, 2);   //TODO: should it be handled as trap? | ||||
| 			X[rd] <= imm; | ||||
| 		} | ||||
| 		// order matters here as C.ADDI16SP overwrites C.LUI vor rd==2 | ||||
| 		C.LUI {//(RV32) | ||||
| 			encoding:b011 | nzimm[17:17]s | rd[4:0] | nzimm[16:12]s | b01; | ||||
| 			args_disass: "x%rd$d, 0x%nzimm$05x"; | ||||
| 			if(rd == 0) raise(0, 2); | ||||
| 			if(rd == 2) raise(0, 2); | ||||
| 			if(nzimm == 0) raise(0, 2); | ||||
| 			X[rd] <= nzimm; | ||||
| 			encoding:b011 | imm[17:17]s | rd[4:0] | imm[16:12]s | b01; | ||||
| 			args_disass: "x%rd$d, 0x%imm$05x"; | ||||
| 			if(rd == 0) raise(0, 2);   //TODO: should it be handled as trap? | ||||
| 			if(imm == 0) raise(0, 2);   //TODO: should it be handled as trap? | ||||
| 			X[rd] <= imm; | ||||
| 		} | ||||
| 		C.ADDI16SP {//(RV32) | ||||
| 			encoding:b011 | nzimm[9:9]s | b00010 | nzimm[4:4]s |nzimm[6:6]s | nzimm[8:7]s | nzimm[5:5]s | b01; | ||||
| 			args_disass: "0x%nzimm$05x"; | ||||
| 			encoding:b011 | imm[9:9]s | b00010 | imm[4:4]s | imm[6:6]s | imm[8:7]s | imm[5:5]s | b01; | ||||
| 			args_disass: "0x%imm$05x"; | ||||
| 			val x2_idx[5] <= 2; | ||||
| 			X[x2_idx] <= X[x2_idx]s + nzimm; | ||||
| 			X[x2_idx] <= X[x2_idx]s + imm; | ||||
| 		} | ||||
| 		C.SRLI {//(RV32 nse) | ||||
| 			encoding:b100 | shamt[5:5] | b00 | rs1[2:0] | shamt[4:0] | b01; | ||||
| 			encoding:b100 | b0 | b00 | rs1[2:0] | shamt[4:0] | b01; | ||||
| 			args_disass: "x(8+%rs1$d), %shamt$d"; | ||||
|             if(shamt > 31) raise(0, 2); | ||||
| 			val rs1_idx[5] <= rs1+8; | ||||
| 			X[rs1_idx] <= shrl(X[rs1_idx], shamt); | ||||
| 		} | ||||
| 		C.SRAI {//(RV32) | ||||
| 			encoding:b100 | shamt[5:5] | b01 | rs1[2:0] | shamt[4:0] | b01; | ||||
| 			encoding:b100 | b0 | b01 | rs1[2:0] | shamt[4:0] | b01; | ||||
| 			args_disass: "x(8+%rs1$d), %shamt$d"; | ||||
| 			if(shamt > 31) raise(0, 2); | ||||
| 			val rs1_idx[5] <= rs1+8; | ||||
| 			X[rs1_idx] <= shra(X[rs1_idx], shamt); | ||||
| 		} | ||||
| @@ -132,27 +124,23 @@ InsructionSet RV32CI { | ||||
| 			PC<=PC+imm; | ||||
| 		} | ||||
| 		C.BEQZ(no_cont) {//(RV32) | ||||
| 			encoding:b110 | imm[8:8]s | imm[4:3]s | rs1d[2:0] | imm[7:6]s |imm[2:1]s | imm[5:5]s | b01; | ||||
| 			args_disass: "x(8+%rs1d$d), 0x%imm$05x"; | ||||
| 			val rs1[5] <= rs1d+8; | ||||
| 			PC<=choose(X[rs1]==0, PC+imm, PC+2); | ||||
| 			encoding:b110 | imm[8:8]s | imm[4:3]s | rs1[2:0] | imm[7:6]s |imm[2:1]s | imm[5:5]s | b01; | ||||
| 			args_disass: "x(8+%rs1$d), 0x%imm$05x"; | ||||
| 			val rs1_idx[5] <= rs1+8; | ||||
| 			PC<=choose(X[rs1_idx]==0, PC+imm, PC+2); | ||||
| 		} | ||||
| 		C.BNEZ(no_cont) {//(RV32) | ||||
| 			encoding:b111 | imm[8:8] | imm[4:3] | rs1d[2:0] | imm[7:6] | imm[2:1] | imm[5:5] | b01; | ||||
| 			args_disass: "x(8+%rs1d$d),, 0x%imm$05x"; | ||||
|             val rs1[5] <= rs1d+8; | ||||
| 			PC<=choose(X[rs1]!=0, PC+imm, PC+2); | ||||
| 			encoding:b111 | imm[8:8]s | imm[4:3]s | rs1[2:0] | imm[7:6]s | imm[2:1]s | imm[5:5]s | b01; | ||||
| 			args_disass: "x(8+%rs1$d), 0x%imm$05x"; | ||||
|             val rs1_idx[5] <= rs1+8; | ||||
| 			PC<=choose(X[rs1_idx]!=0, PC+imm, PC+2); | ||||
| 		} | ||||
| 		C.SLLI {//(RV32) | ||||
| 			encoding:b000 | shamt[5:5] | rs1[4:0] | shamt[4:0] | b10; | ||||
| 			encoding:b000 | b0 | rs1[4:0] | shamt[4:0] | b10; | ||||
| 			args_disass: "x%rs1$d, %shamt$d"; | ||||
| 			if(rs1 == 0) raise(0, 2); | ||||
| 			if(shamt > 31) raise(0, 2); | ||||
| 			X[rs1] <= shll(X[rs1], shamt); | ||||
| 		} | ||||
| 		C.LQSP {//(RV128) | ||||
| 			encoding:b001 | uimm[5:5] | rd[4:0] | uimm[4:4] | uimm[9:6] | b10; | ||||
| 		} | ||||
| 		C.LWSP {// | ||||
| 			encoding:b010 | uimm[5:5] | rd[4:0] | uimm[4:2] | uimm[7:6] | b10; | ||||
| 			args_disass: "x%rd$d, sp, 0x%uimm$05x"; | ||||
| @@ -160,7 +148,7 @@ InsructionSet RV32CI { | ||||
| 			val offs[XLEN] <= X[x2_idx] + uimm; | ||||
| 			X[rd] <= MEM[offs]{32}; | ||||
| 		} | ||||
| 		// order matters as C.JR is a special case of C.JR | ||||
| 		// order matters as C.JR is a special case of C.MV | ||||
|         C.MV {//(RV32) | ||||
|             encoding:b100 | b0 | rd[4:0] | rs2[4:0] | b10; | ||||
|             args_disass: "x%rd$d, x%rs2$d"; | ||||
| @@ -171,23 +159,23 @@ InsructionSet RV32CI { | ||||
| 			args_disass: "x%rs1$d"; | ||||
| 			PC <= X[rs1]; | ||||
| 		} | ||||
| 		C.EBREAK(no_cont) {//(RV32) | ||||
| 			encoding:b100 | b1 | b00000 | b00000 | b10; | ||||
| 			raise(0, 3); | ||||
| 		} | ||||
|         // order matters as C.JALR is a special case of C.ADD | ||||
|         // order matters as C.EBREAK is a special case of C.JALR which is a special case of C.ADD | ||||
|         C.ADD {//(RV32) | ||||
|             encoding:b100 | b1 | rd[4:0] | rs2[4:0] | b10; | ||||
|             args_disass: "x%rd$d, x%rs2$d"; | ||||
|             X[rd] <= X[rd] + X[rs2]; | ||||
|         	X[rd] <= X[rd] + X[rs2]; | ||||
|         } | ||||
| 		C.JALR(no_cont) {//(RV32) | ||||
| 			encoding:b100 | b1 | rs1[4:0] | b00000 | b10; | ||||
| 			args_disass: "x%rs1$d"; | ||||
| 			val rd[5] <= 1; | ||||
| 			X[rd] <= PC+2; | ||||
| 			val r_idx[5] <= 1; | ||||
| 			X[r_idx] <= PC+2; | ||||
| 			PC<=X[rs1]; | ||||
| 		} | ||||
| 		C.EBREAK(no_cont) {//(RV32) | ||||
| 			encoding:b100 | b1 | b00000 | b00000 | b10; | ||||
| 			raise(0, 3); | ||||
| 		} | ||||
| 		C.SWSP {// | ||||
| 			encoding:b110 | uimm[5:2] | uimm[7:6] | rs2[4:0] | b10; | ||||
|             args_disass: "x2+0x%uimm$05x, x%rs2$d"; | ||||
| @@ -195,6 +183,10 @@ InsructionSet RV32CI { | ||||
|             val offs[XLEN] <= X[x2_idx] + uimm; | ||||
|             MEM[offs]{32} <= X[rs2]; | ||||
| 		} | ||||
| 		DII { | ||||
| 			encoding:b000 | b0 | b00000 | b00000 | b00; | ||||
| 			raise(0, 2); | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -435,6 +435,8 @@ public: | ||||
|     virtual uint64_t leave_trap(uint64_t flags) override; | ||||
|     void wait_until(uint64_t flags) override; | ||||
|  | ||||
|     void notify_phase(iss::arch_if::exec_phase phase); | ||||
|  | ||||
|     void disass_output(uint64_t pc, const std::string instr) override { | ||||
|         std::stringstream s; | ||||
|         s << "[p:" << lvl[this->reg.machine_state] << ";s:0x" << std::hex << std::setfill('0') | ||||
| @@ -468,6 +470,7 @@ protected: | ||||
|  | ||||
| private: | ||||
|     iss::status read_cycle(unsigned addr, reg_t &val); | ||||
|     iss::status read_time(unsigned addr, reg_t &val); | ||||
|     iss::status read_status(unsigned addr, reg_t &val); | ||||
|     iss::status write_status(unsigned addr, reg_t val); | ||||
|     iss::status read_ie(unsigned addr, reg_t &val); | ||||
| @@ -489,6 +492,10 @@ riscv_hart_msu_vp<BASE>::riscv_hart_msu_vp() | ||||
|     for (unsigned addr = mcycle; addr <= hpmcounter31; ++addr) csr_wr_cb[addr] = nullptr; | ||||
|     for (unsigned addr = mcycleh; addr <= hpmcounter31h; ++addr) csr_wr_cb[addr] = nullptr; | ||||
|     // special handling | ||||
|     csr_rd_cb[time] = &riscv_hart_msu_vp<BASE>::read_time; | ||||
|     csr_wr_cb[time] = nullptr; | ||||
|     csr_rd_cb[timeh] = &riscv_hart_msu_vp<BASE>::read_time; | ||||
|     csr_wr_cb[timeh] = nullptr; | ||||
|     csr_rd_cb[mcycle] = &riscv_hart_msu_vp<BASE>::read_cycle; | ||||
|     csr_rd_cb[mcycleh] = &riscv_hart_msu_vp<BASE>::read_cycle; | ||||
|     csr_rd_cb[minstret] = &riscv_hart_msu_vp<BASE>::read_cycle; | ||||
| @@ -781,6 +788,17 @@ template <typename BASE> iss::status riscv_hart_msu_vp<BASE>::read_cycle(unsigne | ||||
|     return iss::Ok; | ||||
| } | ||||
|  | ||||
| template <typename BASE> iss::status riscv_hart_msu_vp<BASE>::read_time(unsigned addr, reg_t &val) { | ||||
| 	uint64_t time_val=this->reg.icount>>12; | ||||
|     if (addr == time) { | ||||
|         val = static_cast<reg_t>(time_val); | ||||
|     } else if (addr == timeh) { | ||||
|         if (sizeof(typename traits<BASE>::reg_t) != 4) return iss::Err; | ||||
|         val = static_cast<reg_t>(time_val >> 32); | ||||
|     } | ||||
|     return iss::Ok; | ||||
| } | ||||
|  | ||||
| template <typename BASE> iss::status riscv_hart_msu_vp<BASE>::read_status(unsigned addr, reg_t &val) { | ||||
|     auto req_priv_lvl = addr >> 8; | ||||
|     if (this->reg.machine_state < req_priv_lvl) throw illegal_instruction_fault(this->fault_data); | ||||
| @@ -862,8 +880,9 @@ iss::status riscv_hart_msu_vp<BASE>::read_mem(phys_addr_t paddr, unsigned length | ||||
|     if ((paddr.val + length) > mem.size()) return iss::Err; | ||||
|     switch (paddr.val) { | ||||
|     case 0x0200BFF8: { // CLINT base, mtime reg | ||||
|         uint64_t mtime = this->reg.icount >> 12 /*12*/; | ||||
|         std::copy((uint8_t *)&mtime, ((uint8_t *)&mtime) + length, data); | ||||
|     	if(sizeof(reg_t)<length) return iss::Err; | ||||
|     	reg_t time_val=this->csr[time]; | ||||
|         std::copy((uint8_t *)&time_val, ((uint8_t *)&time_val) + length, data); | ||||
|     } break; | ||||
|     case 0x10008000: { | ||||
|         const mem_type::page_type &p = mem(paddr.val / mem.page_size); | ||||
| @@ -954,6 +973,11 @@ iss::status riscv_hart_msu_vp<BASE>::write_mem(phys_addr_t paddr, unsigned lengt | ||||
|     return iss::Ok; | ||||
| } | ||||
|  | ||||
| template<typename BASE> | ||||
| inline void riscv_hart_msu_vp<BASE>::notify_phase(iss::arch_if::exec_phase phase) { | ||||
| 	BASE::notify_phase(phase); | ||||
| } | ||||
|  | ||||
| template <typename BASE> void riscv_hart_msu_vp<BASE>::check_interrupt() { | ||||
|     auto status = state.mstatus; | ||||
|     auto ip = csr[mip]; | ||||
|   | ||||
| @@ -148,7 +148,8 @@ protected: | ||||
|     } | ||||
|  | ||||
|     // some compile time constants | ||||
|     enum { MASK16 = 0b1111110001100011, MASK32 = 0b11111111111100000111000001111111 }; | ||||
|     // enum { MASK16 = 0b1111110001100011, MASK32 = 0b11111111111100000111000001111111 }; | ||||
|     enum { MASK16 = 0b1111111111111111, MASK32 = 0b11111111111100000111000001111111 }; | ||||
|     enum { EXTR_MASK16 = MASK16 >> 2, EXTR_MASK32 = MASK32 >> 2 }; | ||||
|     enum { LUT_SIZE = 1 << util::bit_count(EXTR_MASK32), LUT_SIZE_C = 1 << util::bit_count(EXTR_MASK16) }; | ||||
|  | ||||
| @@ -281,7 +282,7 @@ vm_impl<ARCH>::gen_single_inst_behavior(virt_addr_t &pc, unsigned int &inst_cnt, | ||||
|     } catch (trap_access &ta) { | ||||
|         throw trap_access(ta.id, pc.val); | ||||
|     } | ||||
|     if (insn == 0x0000006f) throw simulation_stopped(0); | ||||
|     if (insn == 0x0000006f || (insn&0xffff)==0xa001) throw simulation_stopped(0); // 'J 0' or 'C.J 0' | ||||
|     // curr pc on stack | ||||
|     typename vm_impl<ARCH>::processing_pc_entry addr(*this, pc, paddr); | ||||
|     ++inst_cnt; | ||||
|   | ||||
| @@ -148,7 +148,8 @@ protected: | ||||
|     } | ||||
|  | ||||
|     // some compile time constants | ||||
|     enum { MASK16 = 0b1111110001100011, MASK32 = 0b11111111111100000111000001111111 }; | ||||
|     // enum { MASK16 = 0b1111110001100011, MASK32 = 0b11111111111100000111000001111111 }; | ||||
|     enum { MASK16 = 0b1111111111111111, MASK32 = 0b11111111111100000111000001111111 }; | ||||
|     enum { EXTR_MASK16 = MASK16 >> 2, EXTR_MASK32 = MASK32 >> 2 }; | ||||
|     enum { LUT_SIZE = 1 << util::bit_count(EXTR_MASK32), LUT_SIZE_C = 1 << util::bit_count(EXTR_MASK16) }; | ||||
|  | ||||
| @@ -364,10 +365,10 @@ private: | ||||
|         {16, 0b0100000000000000, 0b1110000000000011, &this_class::__c_lw}, | ||||
|         /* instruction C.SW */ | ||||
|         {16, 0b1100000000000000, 0b1110000000000011, &this_class::__c_sw}, | ||||
|         /* instruction C.NOP */ | ||||
|         {16, 0b0000000000000001, 0b1111111111111111, &this_class::__c_nop}, | ||||
|         /* instruction C.ADDI */ | ||||
|         {16, 0b0000000000000001, 0b1110000000000011, &this_class::__c_addi}, | ||||
|         /* instruction C.NOP */ | ||||
|         {16, 0b0000000000000001, 0b1111111111111111, &this_class::__c_nop}, | ||||
|         /* instruction C.JAL */ | ||||
|         {16, 0b0010000000000001, 0b1110000000000011, &this_class::__c_jal}, | ||||
|         /* instruction C.LI */ | ||||
| @@ -377,9 +378,9 @@ private: | ||||
|         /* instruction C.ADDI16SP */ | ||||
|         {16, 0b0110000100000001, 0b1110111110000011, &this_class::__c_addi16sp}, | ||||
|         /* instruction C.SRLI */ | ||||
|         {16, 0b1000000000000001, 0b1110110000000011, &this_class::__c_srli}, | ||||
|         {16, 0b1000000000000001, 0b1111110000000011, &this_class::__c_srli}, | ||||
|         /* instruction C.SRAI */ | ||||
|         {16, 0b1000010000000001, 0b1110110000000011, &this_class::__c_srai}, | ||||
|         {16, 0b1000010000000001, 0b1111110000000011, &this_class::__c_srai}, | ||||
|         /* instruction C.ANDI */ | ||||
|         {16, 0b1000100000000001, 0b1110110000000011, &this_class::__c_andi}, | ||||
|         /* instruction C.SUB */ | ||||
| @@ -397,23 +398,23 @@ private: | ||||
|         /* instruction C.BNEZ */ | ||||
|         {16, 0b1110000000000001, 0b1110000000000011, &this_class::__c_bnez}, | ||||
|         /* instruction C.SLLI */ | ||||
|         {16, 0b0000000000000010, 0b1110000000000011, &this_class::__c_slli}, | ||||
|         /* instruction C.LQSP */ | ||||
|         {16, 0b0010000000000010, 0b1110000000000011, &this_class::__c_lqsp}, | ||||
|         {16, 0b0000000000000010, 0b1111000000000011, &this_class::__c_slli}, | ||||
|         /* instruction C.LWSP */ | ||||
|         {16, 0b0100000000000010, 0b1110000000000011, &this_class::__c_lwsp}, | ||||
|         /* instruction C.MV */ | ||||
|         {16, 0b1000000000000010, 0b1111000000000011, &this_class::__c_mv}, | ||||
|         /* instruction C.JR */ | ||||
|         {16, 0b1000000000000010, 0b1111000001111111, &this_class::__c_jr}, | ||||
|         /* instruction C.EBREAK */ | ||||
|         {16, 0b1001000000000010, 0b1111111111111111, &this_class::__c_ebreak}, | ||||
|         /* instruction C.ADD */ | ||||
|         {16, 0b1001000000000010, 0b1111000000000011, &this_class::__c_add}, | ||||
|         /* instruction C.JALR */ | ||||
|         {16, 0b1001000000000010, 0b1111000001111111, &this_class::__c_jalr}, | ||||
|         /* instruction C.EBREAK */ | ||||
|         {16, 0b1001000000000010, 0b1111111111111111, &this_class::__c_ebreak}, | ||||
|         /* instruction C.SWSP */ | ||||
|         {16, 0b1100000000000010, 0b1110000000000011, &this_class::__c_swsp}, | ||||
|         /* instruction DII */ | ||||
|         {16, 0b0000000000000000, 0b1111111111111111, &this_class::__dii}, | ||||
|     }; | ||||
|     // instruction LUI | ||||
|     std::tuple<vm::continuation_e, llvm::BasicBlock*> __lui(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ | ||||
| @@ -3353,11 +3354,11 @@ private: | ||||
|         this->gen_sync(iss::PRE_SYNC); | ||||
|      | ||||
|         uint8_t fld_rd_val = 0 | (bit_sub<2,3>(instr)); | ||||
|         uint16_t fld_nzuimm_val = 0 | (bit_sub<5,1>(instr) << 3) | (bit_sub<6,1>(instr) << 2) | (bit_sub<7,4>(instr) << 6) | (bit_sub<11,2>(instr) << 4); | ||||
|         uint16_t fld_imm_val = 0 | (bit_sub<5,1>(instr) << 3) | (bit_sub<6,1>(instr) << 2) | (bit_sub<7,4>(instr) << 6) | (bit_sub<11,2>(instr) << 4); | ||||
|         if(this->disass_enabled){ | ||||
|             /* generate console output when executing the command */ | ||||
|             boost::format ins_fmter("C.ADDI4SPN x%1$d, 0x%2$05x"); | ||||
|             ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_nzuimm_val; | ||||
|             ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_imm_val; | ||||
|             std::vector<llvm::Value*> args { | ||||
|                 this->core_ptr, | ||||
|                 this->gen_const(64, pc.val), | ||||
| @@ -3367,14 +3368,14 @@ private: | ||||
|         } | ||||
|         pc=pc+2; | ||||
|      | ||||
|         if(fld_nzuimm_val == 0){ | ||||
|         if(fld_imm_val == 0){ | ||||
|             this->gen_raise_trap(0, 2); | ||||
|         } | ||||
|         uint8_t rd_idx_val = (fld_rd_val + 8); | ||||
|         uint8_t x2_idx_val = 2; | ||||
|         Value* X_rd_idx_val = this->builder->CreateAdd( | ||||
|             this->gen_reg_load(x2_idx_val, 0), | ||||
|             this->gen_const(32U, fld_nzuimm_val)); | ||||
|             this->gen_const(32U, fld_imm_val)); | ||||
|         this->builder->CreateStore(X_rd_idx_val, get_reg_ptr(rd_idx_val), false); | ||||
|         this->gen_set_pc(pc, traits<ARCH>::NEXT_PC); | ||||
|         this->gen_sync(iss::POST_SYNC); /* call post-sync if needed */ | ||||
| @@ -3406,11 +3407,11 @@ private: | ||||
|         pc=pc+2; | ||||
|      | ||||
|         uint8_t rs1_idx_val = (fld_rs1_val + 8); | ||||
|         Value* adr_val = this->builder->CreateAdd( | ||||
|         uint8_t rd_idx_val = (fld_rd_val + 8); | ||||
|         Value* offs_val = this->builder->CreateAdd( | ||||
|             this->gen_reg_load(rs1_idx_val, 0), | ||||
|             this->gen_const(32U, fld_uimm_val)); | ||||
|         uint8_t rd_idx_val = (fld_rd_val + 8); | ||||
|         Value* X_rd_idx_val = this->gen_read_mem(traits<ARCH>::MEM, adr_val, 32/8); | ||||
|         Value* X_rd_idx_val = this->gen_read_mem(traits<ARCH>::MEM, offs_val, 32/8); | ||||
|         this->builder->CreateStore(X_rd_idx_val, get_reg_ptr(rd_idx_val), false); | ||||
|         this->gen_set_pc(pc, traits<ARCH>::NEXT_PC); | ||||
|         this->gen_sync(iss::POST_SYNC); /* call post-sync if needed */ | ||||
| @@ -3442,15 +3443,47 @@ private: | ||||
|         pc=pc+2; | ||||
|      | ||||
|         uint8_t rs1_idx_val = (fld_rs1_val + 8); | ||||
|         Value* adr_val = this->builder->CreateAdd( | ||||
|         uint8_t rs2_idx_val = (fld_rs2_val + 8); | ||||
|         Value* offs_val = this->builder->CreateAdd( | ||||
|             this->gen_reg_load(rs1_idx_val, 0), | ||||
|             this->gen_const(32U, fld_uimm_val)); | ||||
|         uint8_t rs2_idx_val = (fld_rs2_val + 8); | ||||
|         Value* MEM_adr_val = this->gen_reg_load(rs2_idx_val, 0); | ||||
|         Value* MEM_offs_val = this->gen_reg_load(rs2_idx_val, 0); | ||||
|         this->gen_write_mem( | ||||
|             traits<ARCH>::MEM, | ||||
|             adr_val, | ||||
|             this->builder->CreateZExtOrTrunc(MEM_adr_val,this->get_type(32))); | ||||
|             offs_val, | ||||
|             this->builder->CreateZExtOrTrunc(MEM_offs_val,this->get_type(32))); | ||||
|         this->gen_set_pc(pc, traits<ARCH>::NEXT_PC); | ||||
|         this->gen_sync(iss::POST_SYNC); /* call post-sync if needed */ | ||||
|         bb = llvm::BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ | ||||
|         this->gen_trap_check(bb); | ||||
|         return std::make_tuple(vm::CONT, bb); | ||||
|     } | ||||
|      | ||||
|     // instruction C.ADDI | ||||
|     std::tuple<vm::continuation_e, llvm::BasicBlock*> __c_addi(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ | ||||
|         bb->setName("C.ADDI"); | ||||
|      | ||||
|         this->gen_sync(iss::PRE_SYNC); | ||||
|      | ||||
|         int8_t fld_imm_val = 0 | (bit_sub<2,5>(instr)) | (signed_bit_sub<12,1>(instr) << 5); | ||||
|         uint8_t fld_rs1_val = 0 | (bit_sub<7,5>(instr)); | ||||
|         if(this->disass_enabled){ | ||||
|             /* generate console output when executing the command */ | ||||
|             boost::format ins_fmter("C.ADDI x%1$d, 0x%2$05x"); | ||||
|             ins_fmter % (uint64_t)fld_rs1_val % (int64_t)fld_imm_val; | ||||
|             std::vector<llvm::Value*> args { | ||||
|                 this->core_ptr, | ||||
|                 this->gen_const(64, pc.val), | ||||
|                 this->builder->CreateGlobalStringPtr(ins_fmter.str()), | ||||
|             }; | ||||
|             this->builder->CreateCall(this->mod->getFunction("print_disass"), args); | ||||
|         } | ||||
|         pc=pc+2; | ||||
|      | ||||
|         Value* X_rs1_val = this->builder->CreateAdd( | ||||
|             this->gen_reg_load(fld_rs1_val, 0), | ||||
|             this->gen_const(32U, fld_imm_val)); | ||||
|         this->builder->CreateStore(X_rs1_val, get_reg_ptr(fld_rs1_val), false); | ||||
|         this->gen_set_pc(pc, traits<ARCH>::NEXT_PC); | ||||
|         this->gen_sync(iss::POST_SYNC); /* call post-sync if needed */ | ||||
|         bb = llvm::BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ | ||||
| @@ -3467,12 +3500,10 @@ private: | ||||
|         ; | ||||
|         if(this->disass_enabled){ | ||||
|             /* generate console output when executing the command */ | ||||
|             boost::format ins_fmter("C.NOP "); | ||||
|             ins_fmter ; | ||||
|             std::vector<llvm::Value*> args { | ||||
|                 this->core_ptr, | ||||
|                 this->gen_const(64, pc.val), | ||||
|                 this->builder->CreateGlobalStringPtr(ins_fmter.str()), | ||||
|                 this->builder->CreateGlobalStringPtr("C.NOP"), | ||||
|             }; | ||||
|             this->builder->CreateCall(this->mod->getFunction("print_disass"), args); | ||||
|         } | ||||
| @@ -3486,41 +3517,6 @@ private: | ||||
|         return std::make_tuple(vm::CONT, bb); | ||||
|     } | ||||
|      | ||||
|     // instruction C.ADDI | ||||
|     std::tuple<vm::continuation_e, llvm::BasicBlock*> __c_addi(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ | ||||
|         bb->setName("C.ADDI"); | ||||
|      | ||||
|         this->gen_sync(iss::PRE_SYNC); | ||||
|      | ||||
|         int8_t fld_nzimm_val = 0 | (bit_sub<2,5>(instr)) | (signed_bit_sub<12,1>(instr) << 5); | ||||
|         uint8_t fld_rs1_val = 0 | (bit_sub<7,5>(instr)); | ||||
|         if(this->disass_enabled){ | ||||
|             /* generate console output when executing the command */ | ||||
|             boost::format ins_fmter("C.ADDI x%1$d, 0x%2$05x"); | ||||
|             ins_fmter % (uint64_t)fld_rs1_val % (int64_t)fld_nzimm_val; | ||||
|             std::vector<llvm::Value*> args { | ||||
|                 this->core_ptr, | ||||
|                 this->gen_const(64, pc.val), | ||||
|                 this->builder->CreateGlobalStringPtr(ins_fmter.str()), | ||||
|             }; | ||||
|             this->builder->CreateCall(this->mod->getFunction("print_disass"), args); | ||||
|         } | ||||
|         pc=pc+2; | ||||
|      | ||||
|         if(fld_nzimm_val == 0){ | ||||
|             this->gen_raise_trap(0, 2); | ||||
|         } | ||||
|         Value* X_rs1_val = this->builder->CreateAdd( | ||||
|             this->gen_reg_load(fld_rs1_val, 0), | ||||
|             this->gen_const(32U, fld_nzimm_val)); | ||||
|         this->builder->CreateStore(X_rs1_val, get_reg_ptr(fld_rs1_val), false); | ||||
|         this->gen_set_pc(pc, traits<ARCH>::NEXT_PC); | ||||
|         this->gen_sync(iss::POST_SYNC); /* call post-sync if needed */ | ||||
|         bb = llvm::BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ | ||||
|         this->gen_trap_check(bb); | ||||
|         return std::make_tuple(vm::CONT, bb); | ||||
|     } | ||||
|      | ||||
|     // instruction C.JAL | ||||
|     std::tuple<vm::continuation_e, llvm::BasicBlock*> __c_jal(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ | ||||
|         bb->setName("C.JAL"); | ||||
| @@ -3594,12 +3590,12 @@ private: | ||||
|      | ||||
|         this->gen_sync(iss::PRE_SYNC); | ||||
|      | ||||
|         int32_t fld_nzimm_val = 0 | (bit_sub<2,5>(instr) << 12) | (signed_bit_sub<12,1>(instr) << 17); | ||||
|         int32_t fld_imm_val = 0 | (bit_sub<2,5>(instr) << 12) | (signed_bit_sub<12,1>(instr) << 17); | ||||
|         uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); | ||||
|         if(this->disass_enabled){ | ||||
|             /* generate console output when executing the command */ | ||||
|             boost::format ins_fmter("C.LUI x%1$d, 0x%2$05x"); | ||||
|             ins_fmter % (uint64_t)fld_rd_val % (int64_t)fld_nzimm_val; | ||||
|             ins_fmter % (uint64_t)fld_rd_val % (int64_t)fld_imm_val; | ||||
|             std::vector<llvm::Value*> args { | ||||
|                 this->core_ptr, | ||||
|                 this->gen_const(64, pc.val), | ||||
| @@ -3612,13 +3608,10 @@ private: | ||||
|         if(fld_rd_val == 0){ | ||||
|             this->gen_raise_trap(0, 2); | ||||
|         } | ||||
|         if(fld_rd_val == 2){ | ||||
|         if(fld_imm_val == 0){ | ||||
|             this->gen_raise_trap(0, 2); | ||||
|         } | ||||
|         if(fld_nzimm_val == 0){ | ||||
|             this->gen_raise_trap(0, 2); | ||||
|         } | ||||
|         Value* X_rd_val = this->gen_const(32U, fld_nzimm_val); | ||||
|         Value* X_rd_val = this->gen_const(32U, fld_imm_val); | ||||
|         this->builder->CreateStore(X_rd_val, get_reg_ptr(fld_rd_val), false); | ||||
|         this->gen_set_pc(pc, traits<ARCH>::NEXT_PC); | ||||
|         this->gen_sync(iss::POST_SYNC); /* call post-sync if needed */ | ||||
| @@ -3633,11 +3626,11 @@ private: | ||||
|      | ||||
|         this->gen_sync(iss::PRE_SYNC); | ||||
|      | ||||
|         int16_t fld_nzimm_val = 0 | (bit_sub<2,1>(instr) << 5) | (bit_sub<3,2>(instr) << 7) | (bit_sub<5,1>(instr) << 6) | (bit_sub<6,1>(instr) << 4) | (signed_bit_sub<12,1>(instr) << 9); | ||||
|         int16_t fld_imm_val = 0 | (bit_sub<2,1>(instr) << 5) | (bit_sub<3,2>(instr) << 7) | (bit_sub<5,1>(instr) << 6) | (bit_sub<6,1>(instr) << 4) | (signed_bit_sub<12,1>(instr) << 9); | ||||
|         if(this->disass_enabled){ | ||||
|             /* generate console output when executing the command */ | ||||
|             boost::format ins_fmter("C.ADDI16SP 0x%1$05x"); | ||||
|             ins_fmter % (int64_t)fld_nzimm_val; | ||||
|             ins_fmter % (int64_t)fld_imm_val; | ||||
|             std::vector<llvm::Value*> args { | ||||
|                 this->core_ptr, | ||||
|                 this->gen_const(64, pc.val), | ||||
| @@ -3652,7 +3645,7 @@ private: | ||||
|             this->gen_ext( | ||||
|                 this->gen_reg_load(x2_idx_val, 0), | ||||
|                 32, true), | ||||
|             this->gen_const(32U, fld_nzimm_val)); | ||||
|             this->gen_const(32U, fld_imm_val)); | ||||
|         this->builder->CreateStore(X_x2_idx_val, get_reg_ptr(x2_idx_val), false); | ||||
|         this->gen_set_pc(pc, traits<ARCH>::NEXT_PC); | ||||
|         this->gen_sync(iss::POST_SYNC); /* call post-sync if needed */ | ||||
| @@ -3667,7 +3660,7 @@ private: | ||||
|      | ||||
|         this->gen_sync(iss::PRE_SYNC); | ||||
|      | ||||
|         uint8_t fld_shamt_val = 0 | (bit_sub<2,5>(instr)) | (bit_sub<12,1>(instr) << 5); | ||||
|         uint8_t fld_shamt_val = 0 | (bit_sub<2,5>(instr)); | ||||
|         uint8_t fld_rs1_val = 0 | (bit_sub<7,3>(instr)); | ||||
|         if(this->disass_enabled){ | ||||
|             /* generate console output when executing the command */ | ||||
| @@ -3682,9 +3675,6 @@ private: | ||||
|         } | ||||
|         pc=pc+2; | ||||
|      | ||||
|         if(fld_shamt_val > 31){ | ||||
|             this->gen_raise_trap(0, 2); | ||||
|         } | ||||
|         uint8_t rs1_idx_val = (fld_rs1_val + 8); | ||||
|         Value* X_rs1_idx_val = this->builder->CreateLShr( | ||||
|             this->gen_reg_load(rs1_idx_val, 0), | ||||
| @@ -3703,7 +3693,7 @@ private: | ||||
|      | ||||
|         this->gen_sync(iss::PRE_SYNC); | ||||
|      | ||||
|         uint8_t fld_shamt_val = 0 | (bit_sub<2,5>(instr)) | (bit_sub<12,1>(instr) << 5); | ||||
|         uint8_t fld_shamt_val = 0 | (bit_sub<2,5>(instr)); | ||||
|         uint8_t fld_rs1_val = 0 | (bit_sub<7,3>(instr)); | ||||
|         if(this->disass_enabled){ | ||||
|             /* generate console output when executing the command */ | ||||
| @@ -3718,9 +3708,6 @@ private: | ||||
|         } | ||||
|         pc=pc+2; | ||||
|      | ||||
|         if(fld_shamt_val > 31){ | ||||
|             this->gen_raise_trap(0, 2); | ||||
|         } | ||||
|         uint8_t rs1_idx_val = (fld_rs1_val + 8); | ||||
|         Value* X_rs1_idx_val = this->builder->CreateAShr( | ||||
|             this->gen_reg_load(rs1_idx_val, 0), | ||||
| @@ -3938,11 +3925,11 @@ private: | ||||
|         this->gen_sync(iss::PRE_SYNC); | ||||
|      | ||||
|         int16_t fld_imm_val = 0 | (bit_sub<2,1>(instr) << 5) | (bit_sub<3,2>(instr) << 1) | (bit_sub<5,2>(instr) << 6) | (bit_sub<10,2>(instr) << 3) | (signed_bit_sub<12,1>(instr) << 8); | ||||
|         uint8_t fld_rs1d_val = 0 | (bit_sub<7,3>(instr)); | ||||
|         uint8_t fld_rs1_val = 0 | (bit_sub<7,3>(instr)); | ||||
|         if(this->disass_enabled){ | ||||
|             /* generate console output when executing the command */ | ||||
|             boost::format ins_fmter("C.BEQZ x(8+%1$d), 0x%2$05x"); | ||||
|             ins_fmter % (uint64_t)fld_rs1d_val % (int64_t)fld_imm_val; | ||||
|             ins_fmter % (uint64_t)fld_rs1_val % (int64_t)fld_imm_val; | ||||
|             std::vector<llvm::Value*> args { | ||||
|                 this->core_ptr, | ||||
|                 this->gen_const(64, pc.val), | ||||
| @@ -3952,11 +3939,11 @@ private: | ||||
|         } | ||||
|         pc=pc+2; | ||||
|      | ||||
|         uint8_t rs1_val = (fld_rs1d_val + 8); | ||||
|         uint8_t rs1_idx_val = (fld_rs1_val + 8); | ||||
|         Value* PC_val = this->gen_choose( | ||||
|             this->builder->CreateICmp( | ||||
|                 ICmpInst::ICMP_EQ, | ||||
|                 this->gen_reg_load(rs1_val, 0), | ||||
|                 this->gen_reg_load(rs1_idx_val, 0), | ||||
|                 this->gen_const(32U, 0)), | ||||
|             this->builder->CreateAdd( | ||||
|                 this->gen_reg_load(traits<ARCH>::PC, 0), | ||||
| @@ -3977,12 +3964,12 @@ private: | ||||
|      | ||||
|         this->gen_sync(iss::PRE_SYNC); | ||||
|      | ||||
|         uint16_t fld_imm_val = 0 | (bit_sub<2,1>(instr) << 5) | (bit_sub<3,2>(instr) << 1) | (bit_sub<5,2>(instr) << 6) | (bit_sub<10,2>(instr) << 3) | (bit_sub<12,1>(instr) << 8); | ||||
|         uint8_t fld_rs1d_val = 0 | (bit_sub<7,3>(instr)); | ||||
|         int16_t fld_imm_val = 0 | (bit_sub<2,1>(instr) << 5) | (bit_sub<3,2>(instr) << 1) | (bit_sub<5,2>(instr) << 6) | (bit_sub<10,2>(instr) << 3) | (signed_bit_sub<12,1>(instr) << 8); | ||||
|         uint8_t fld_rs1_val = 0 | (bit_sub<7,3>(instr)); | ||||
|         if(this->disass_enabled){ | ||||
|             /* generate console output when executing the command */ | ||||
|             boost::format ins_fmter("C.BNEZ x(8+%1$d),, 0x%2$05x"); | ||||
|             ins_fmter % (uint64_t)fld_rs1d_val % (uint64_t)fld_imm_val; | ||||
|             boost::format ins_fmter("C.BNEZ x(8+%1$d), 0x%2$05x"); | ||||
|             ins_fmter % (uint64_t)fld_rs1_val % (int64_t)fld_imm_val; | ||||
|             std::vector<llvm::Value*> args { | ||||
|                 this->core_ptr, | ||||
|                 this->gen_const(64, pc.val), | ||||
| @@ -3992,11 +3979,11 @@ private: | ||||
|         } | ||||
|         pc=pc+2; | ||||
|      | ||||
|         uint8_t rs1_val = (fld_rs1d_val + 8); | ||||
|         uint8_t rs1_idx_val = (fld_rs1_val + 8); | ||||
|         Value* PC_val = this->gen_choose( | ||||
|             this->builder->CreateICmp( | ||||
|                 ICmpInst::ICMP_NE, | ||||
|                 this->gen_reg_load(rs1_val, 0), | ||||
|                 this->gen_reg_load(rs1_idx_val, 0), | ||||
|                 this->gen_const(32U, 0)), | ||||
|             this->builder->CreateAdd( | ||||
|                 this->gen_reg_load(traits<ARCH>::PC, 0), | ||||
| @@ -4017,7 +4004,7 @@ private: | ||||
|      | ||||
|         this->gen_sync(iss::PRE_SYNC); | ||||
|      | ||||
|         uint8_t fld_shamt_val = 0 | (bit_sub<2,5>(instr)) | (bit_sub<12,1>(instr) << 5); | ||||
|         uint8_t fld_shamt_val = 0 | (bit_sub<2,5>(instr)); | ||||
|         uint8_t fld_rs1_val = 0 | (bit_sub<7,5>(instr)); | ||||
|         if(this->disass_enabled){ | ||||
|             /* generate console output when executing the command */ | ||||
| @@ -4035,9 +4022,6 @@ private: | ||||
|         if(fld_rs1_val == 0){ | ||||
|             this->gen_raise_trap(0, 2); | ||||
|         } | ||||
|         if(fld_shamt_val > 31){ | ||||
|             this->gen_raise_trap(0, 2); | ||||
|         } | ||||
|         Value* X_rs1_val = this->builder->CreateShl( | ||||
|             this->gen_reg_load(fld_rs1_val, 0), | ||||
|             this->gen_const(32U, fld_shamt_val)); | ||||
| @@ -4049,33 +4033,6 @@ private: | ||||
|         return std::make_tuple(vm::CONT, bb); | ||||
|     } | ||||
|      | ||||
|     // instruction C.LQSP | ||||
|     std::tuple<vm::continuation_e, llvm::BasicBlock*> __c_lqsp(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ | ||||
|         bb->setName("C.LQSP"); | ||||
|      | ||||
|         this->gen_sync(iss::PRE_SYNC); | ||||
|      | ||||
|         uint16_t fld_uimm_val = 0 | (bit_sub<2,4>(instr) << 6) | (bit_sub<6,1>(instr) << 4) | (bit_sub<12,1>(instr) << 5); | ||||
|         uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); | ||||
|         if(this->disass_enabled){ | ||||
|             /* generate console output when executing the command */ | ||||
|             std::vector<llvm::Value*> args { | ||||
|                 this->core_ptr, | ||||
|                 this->gen_const(64, pc.val), | ||||
|                 this->builder->CreateGlobalStringPtr("C.LQSP"), | ||||
|             }; | ||||
|             this->builder->CreateCall(this->mod->getFunction("print_disass"), args); | ||||
|         } | ||||
|         pc=pc+2; | ||||
|      | ||||
|         /* TODO: describe operations for C.LQSP ! */ | ||||
|         this->gen_set_pc(pc, traits<ARCH>::NEXT_PC); | ||||
|         this->gen_sync(iss::POST_SYNC); /* call post-sync if needed */ | ||||
|         bb = llvm::BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ | ||||
|         this->gen_trap_check(bb); | ||||
|         return std::make_tuple(vm::CONT, bb); | ||||
|     } | ||||
|      | ||||
|     // instruction C.LWSP | ||||
|     std::tuple<vm::continuation_e, llvm::BasicBlock*> __c_lwsp(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ | ||||
|         bb->setName("C.LWSP"); | ||||
| @@ -4167,30 +4124,6 @@ private: | ||||
|         return std::make_tuple(iss::vm::BRANCH, nullptr); | ||||
|     } | ||||
|      | ||||
|     // instruction C.EBREAK | ||||
|     std::tuple<vm::continuation_e, llvm::BasicBlock*> __c_ebreak(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ | ||||
|         bb->setName("C.EBREAK"); | ||||
|      | ||||
|         this->gen_sync(iss::PRE_SYNC); | ||||
|      | ||||
|         ; | ||||
|         if(this->disass_enabled){ | ||||
|             /* generate console output when executing the command */ | ||||
|             std::vector<llvm::Value*> args { | ||||
|                 this->core_ptr, | ||||
|                 this->gen_const(64, pc.val), | ||||
|                 this->builder->CreateGlobalStringPtr("C.EBREAK"), | ||||
|             }; | ||||
|             this->builder->CreateCall(this->mod->getFunction("print_disass"), args); | ||||
|         } | ||||
|         pc=pc+2; | ||||
|      | ||||
|         this->gen_raise_trap(0, 3); | ||||
|         this->gen_sync(iss::POST_SYNC); /* call post-sync if needed */ | ||||
|         this->gen_trap_check(this->leave_blk); | ||||
|         return std::make_tuple(iss::vm::BRANCH, nullptr); | ||||
|     } | ||||
|      | ||||
|     // instruction C.ADD | ||||
|     std::tuple<vm::continuation_e, llvm::BasicBlock*> __c_add(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ | ||||
|         bb->setName("C.ADD"); | ||||
| @@ -4243,11 +4176,11 @@ private: | ||||
|         } | ||||
|         pc=pc+2; | ||||
|      | ||||
|         uint8_t rd_val = 1; | ||||
|         Value* X_rd_val = this->builder->CreateAdd( | ||||
|         uint8_t r_idx_val = 1; | ||||
|         Value* X_r_idx_val = this->builder->CreateAdd( | ||||
|             this->gen_reg_load(traits<ARCH>::PC, 0), | ||||
|             this->gen_const(32U, 2)); | ||||
|         this->builder->CreateStore(X_rd_val, get_reg_ptr(rd_val), false); | ||||
|         this->builder->CreateStore(X_r_idx_val, get_reg_ptr(r_idx_val), false); | ||||
|         Value* PC_val = this->gen_reg_load(fld_rs1_val, 0); | ||||
|         this->builder->CreateStore(PC_val, get_reg_ptr(traits<ARCH>::NEXT_PC), false); | ||||
|         this->gen_sync(iss::POST_SYNC); /* call post-sync if needed */ | ||||
| @@ -4255,6 +4188,30 @@ private: | ||||
|         return std::make_tuple(iss::vm::BRANCH, nullptr); | ||||
|     } | ||||
|      | ||||
|     // instruction C.EBREAK | ||||
|     std::tuple<vm::continuation_e, llvm::BasicBlock*> __c_ebreak(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ | ||||
|         bb->setName("C.EBREAK"); | ||||
|      | ||||
|         this->gen_sync(iss::PRE_SYNC); | ||||
|      | ||||
|         ; | ||||
|         if(this->disass_enabled){ | ||||
|             /* generate console output when executing the command */ | ||||
|             std::vector<llvm::Value*> args { | ||||
|                 this->core_ptr, | ||||
|                 this->gen_const(64, pc.val), | ||||
|                 this->builder->CreateGlobalStringPtr("C.EBREAK"), | ||||
|             }; | ||||
|             this->builder->CreateCall(this->mod->getFunction("print_disass"), args); | ||||
|         } | ||||
|         pc=pc+2; | ||||
|      | ||||
|         this->gen_raise_trap(0, 3); | ||||
|         this->gen_sync(iss::POST_SYNC); /* call post-sync if needed */ | ||||
|         this->gen_trap_check(this->leave_blk); | ||||
|         return std::make_tuple(iss::vm::BRANCH, nullptr); | ||||
|     } | ||||
|      | ||||
|     // instruction C.SWSP | ||||
|     std::tuple<vm::continuation_e, llvm::BasicBlock*> __c_swsp(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ | ||||
|         bb->setName("C.SWSP"); | ||||
| @@ -4292,6 +4249,32 @@ private: | ||||
|         return std::make_tuple(vm::CONT, bb); | ||||
|     } | ||||
|      | ||||
|     // instruction DII | ||||
|     std::tuple<vm::continuation_e, llvm::BasicBlock*> __dii(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ | ||||
|         bb->setName("DII"); | ||||
|      | ||||
|         this->gen_sync(iss::PRE_SYNC); | ||||
|      | ||||
|         ; | ||||
|         if(this->disass_enabled){ | ||||
|             /* generate console output when executing the command */ | ||||
|             std::vector<llvm::Value*> args { | ||||
|                 this->core_ptr, | ||||
|                 this->gen_const(64, pc.val), | ||||
|                 this->builder->CreateGlobalStringPtr("DII"), | ||||
|             }; | ||||
|             this->builder->CreateCall(this->mod->getFunction("print_disass"), args); | ||||
|         } | ||||
|         pc=pc+2; | ||||
|      | ||||
|         this->gen_raise_trap(0, 2); | ||||
|         this->gen_set_pc(pc, traits<ARCH>::NEXT_PC); | ||||
|         this->gen_sync(iss::POST_SYNC); /* call post-sync if needed */ | ||||
|         bb = llvm::BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ | ||||
|         this->gen_trap_check(bb); | ||||
|         return std::make_tuple(vm::CONT, bb); | ||||
|     } | ||||
|      | ||||
| /* end generated code  */ | ||||
|     /**************************************************************************** | ||||
|      * end opcode definitions | ||||
| @@ -4358,7 +4341,7 @@ vm_impl<ARCH>::gen_single_inst_behavior(virt_addr_t &pc, unsigned int &inst_cnt, | ||||
|     } catch (trap_access &ta) { | ||||
|         throw trap_access(ta.id, pc.val); | ||||
|     } | ||||
|     if (insn == 0x0000006f) throw simulation_stopped(0); | ||||
|     if (insn == 0x0000006f || (insn&0xffff)==0xa001) throw simulation_stopped(0); // 'J 0' or 'C.J 0' | ||||
|     // curr pc on stack | ||||
|     typename vm_impl<ARCH>::processing_pc_entry addr(*this, pc, paddr); | ||||
|     ++inst_cnt; | ||||
|   | ||||
 Submodule sc-components updated: fbd3247649...ba65d9f172
									
								
							
		Reference in New Issue
	
	Block a user