Compare commits
	
		
			1 Commits
		
	
	
		
			23b9741adf
			...
			2f4b5bd9b2
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 2f4b5bd9b2 | 
 Submodule gen_input/CoreDSL-Instruction-Set-Description updated: 0c70a41376...98cddb2999
									
								
							| @@ -152,16 +152,28 @@ public: | |||||||
|             mstatus = new_val; |             mstatus = new_val; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         T satp; |  | ||||||
|  |  | ||||||
|         static constexpr uint32_t get_mask() { |         static constexpr uint32_t get_mask() { | ||||||
|             return 0x807ff9ddUL; // 0b1000 0000 0111 1111 1111 1001 1011 1011  // only machine mode is supported |             //return 0x807ff988UL; // 0b1000 0000 0111 1111 1111 1000 1000 1000  // only machine mode is supported | ||||||
|  |             //       +-SD | ||||||
|  |             //       |        +-TSR | ||||||
|  |             //       |        |+-TW | ||||||
|  |             //       |        ||+-TVM | ||||||
|  |             //       |        |||+-MXR | ||||||
|  |             //       |        ||||+-SUM | ||||||
|  |             //       |        |||||+-MPRV | ||||||
|  |             //       |        |||||| +-XS | ||||||
|  |             //       |        |||||| | +-FS | ||||||
|  |             //       |        |||||| | | +-MPP | ||||||
|  |             //       |        |||||| | | |  +-SPP | ||||||
|  |             //       |        |||||| | | |  |+-MPIE | ||||||
|  |             //       |        ||||||/|/|/|  ||   +-MIE | ||||||
|  |             return 0b00000000000000000001100010001000; | ||||||
|         } |         } | ||||||
|     }; |     }; | ||||||
|     using hart_state_type = hart_state<reg_t>; |     using hart_state_type = hart_state<reg_t>; | ||||||
|  |  | ||||||
|     constexpr reg_t get_irq_mask() { |     constexpr reg_t get_irq_mask() { | ||||||
|         return 0b101110111011; // only machine mode is supported |         return 0b100010001000; // only machine mode is supported | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     riscv_hart_m_p(); |     riscv_hart_m_p(); | ||||||
| @@ -286,7 +298,12 @@ template <typename BASE> | |||||||
| riscv_hart_m_p<BASE>::riscv_hart_m_p() | riscv_hart_m_p<BASE>::riscv_hart_m_p() | ||||||
| : state() | : state() | ||||||
| , instr_if(*this) { | , instr_if(*this) { | ||||||
|  |     // reset values | ||||||
|     csr[misa] = traits<BASE>::MISA_VAL; |     csr[misa] = traits<BASE>::MISA_VAL; | ||||||
|  |     csr[mvendorid] = 0x669; | ||||||
|  |     csr[marchid] = 0x80000003; | ||||||
|  |     csr[mimpid] = 1; | ||||||
|  |  | ||||||
|     uart_buf.str(""); |     uart_buf.str(""); | ||||||
|     for (unsigned addr = mhpmcounter3; addr <= mhpmcounter31; ++addr){ |     for (unsigned addr = mhpmcounter3; addr <= mhpmcounter31; ++addr){ | ||||||
|         csr_rd_cb[addr] = &this_class::read_null; |         csr_rd_cb[addr] = &this_class::read_null; | ||||||
| @@ -309,7 +326,7 @@ riscv_hart_m_p<BASE>::riscv_hart_m_p() | |||||||
|         csr_wr_cb[addr] = &this_class::write_reg; |         csr_wr_cb[addr] = &this_class::write_reg; | ||||||
|     } |     } | ||||||
|     // common regs |     // common regs | ||||||
|     const std::array<unsigned, 7> addrs{{misa, mepc, mtvec, mscratch, mcause, mtval, mscratch}}; |     const std::array<unsigned, 10> addrs{{misa, mvendorid, marchid, mimpid, mepc, mtvec, mscratch, mcause, mtval, mscratch}}; | ||||||
|     for(auto addr: addrs) { |     for(auto addr: addrs) { | ||||||
|         csr_rd_cb[addr] = &this_class::read_reg; |         csr_rd_cb[addr] = &this_class::read_reg; | ||||||
|         csr_wr_cb[addr] = &this_class::write_reg; |         csr_wr_cb[addr] = &this_class::write_reg; | ||||||
| @@ -338,6 +355,9 @@ riscv_hart_m_p<BASE>::riscv_hart_m_p() | |||||||
|     csr_wr_cb[mcounteren] = &this_class::write_null; |     csr_wr_cb[mcounteren] = &this_class::write_null; | ||||||
|     csr_rd_cb[mtvec] = &this_class::read_mtvec; |     csr_rd_cb[mtvec] = &this_class::read_mtvec; | ||||||
|     csr_wr_cb[misa] = &this_class::write_null; |     csr_wr_cb[misa] = &this_class::write_null; | ||||||
|  |     csr_wr_cb[mvendorid] = &this_class::write_null; | ||||||
|  |     csr_wr_cb[marchid] = &this_class::write_null; | ||||||
|  |     csr_wr_cb[mimpid] = &this_class::write_null; | ||||||
| } | } | ||||||
|  |  | ||||||
| template <typename BASE> std::pair<uint64_t, bool> riscv_hart_m_p<BASE>::load_file(std::string name, int type) { | template <typename BASE> std::pair<uint64_t, bool> riscv_hart_m_p<BASE>::load_file(std::string name, int type) { | ||||||
| @@ -406,13 +426,23 @@ iss::status riscv_hart_m_p<BASE>::read(const address_type type, const access_typ | |||||||
|                 return iss::Err; |                 return iss::Err; | ||||||
|             } |             } | ||||||
|             try { |             try { | ||||||
|  |                 auto alignment = access == iss::access_type::FETCH? (traits<BASE>::MISA_VAL&0x100? 2 : 4) : length; | ||||||
|  |                 if(alignment>1 && (addr&(alignment-1))){ | ||||||
|  |                     this->reg.trap_state = 1<<31 | 4<<16; | ||||||
|  |                     fault_data=addr; | ||||||
|  |                     return iss::Err; | ||||||
|  |                 } | ||||||
|                 auto res = type==iss::address_type::PHYSICAL? |                 auto res = type==iss::address_type::PHYSICAL? | ||||||
|                         read_mem( BASE::v2p(phys_addr_t{access, space, addr}), length, data): |                         read_mem( BASE::v2p(phys_addr_t{access, space, addr}), length, data): | ||||||
|                         read_mem( BASE::v2p(iss::addr_t{access, type, space, addr}), length, data); |                         read_mem( BASE::v2p(iss::addr_t{access, type, space, addr}), length, data); | ||||||
|                 if (unlikely(res != iss::Ok)) this->reg.trap_state = (1 << 31) | (5 << 16); // issue trap 5 (load access fault |                 if (unlikely(res != iss::Ok)){ | ||||||
|  |                     this->reg.trap_state = (1 << 31) | (5 << 16); // issue trap 5 (load access fault | ||||||
|  |                     fault_data=addr; | ||||||
|  |                 } | ||||||
|                 return res; |                 return res; | ||||||
|             } catch (trap_access &ta) { |             } catch (trap_access &ta) { | ||||||
|                 this->reg.trap_state = (1 << 31) | ta.id; |                 this->reg.trap_state = (1 << 31) | ta.id; | ||||||
|  |                 fault_data=ta.addr; | ||||||
|                 return iss::Err; |                 return iss::Err; | ||||||
|             } |             } | ||||||
|         } break; |         } break; | ||||||
| @@ -438,6 +468,7 @@ iss::status riscv_hart_m_p<BASE>::read(const address_type type, const access_typ | |||||||
|         return iss::Ok; |         return iss::Ok; | ||||||
|     } catch (trap_access &ta) { |     } catch (trap_access &ta) { | ||||||
|         this->reg.trap_state = (1 << 31) | ta.id; |         this->reg.trap_state = (1 << 31) | ta.id; | ||||||
|  |         fault_data=ta.addr; | ||||||
|         return iss::Err; |         return iss::Err; | ||||||
|     } |     } | ||||||
| } | } | ||||||
| @@ -478,14 +509,22 @@ iss::status riscv_hart_m_p<BASE>::write(const address_type type, const access_ty | |||||||
|                 return iss::Err; |                 return iss::Err; | ||||||
|             } |             } | ||||||
|             try { |             try { | ||||||
|  |                 if(length>1 && (addr&(length-1))){ | ||||||
|  |                     this->reg.trap_state = 1<<31 | 6<<16; | ||||||
|  |                     fault_data=addr; | ||||||
|  |                     return iss::Err; | ||||||
|  |                 } | ||||||
|                 auto res = type==iss::address_type::PHYSICAL? |                 auto res = type==iss::address_type::PHYSICAL? | ||||||
|                         write_mem(phys_addr_t{access, space, addr}, length, data): |                         write_mem(phys_addr_t{access, space, addr}, length, data): | ||||||
|                         write_mem(BASE::v2p(iss::addr_t{access, type, space, addr}), length, data); |                         write_mem(BASE::v2p(iss::addr_t{access, type, space, addr}), length, data); | ||||||
|                 if (unlikely(res != iss::Ok)) |                 if (unlikely(res != iss::Ok)) { | ||||||
|                     this->reg.trap_state = (1 << 31) | (5 << 16); // issue trap 7 (Store/AMO access fault) |                     this->reg.trap_state = (1 << 31) | (7 << 16); // issue trap 7 (Store/AMO access fault) | ||||||
|  |                     fault_data=addr; | ||||||
|  |                 } | ||||||
|                 return res; |                 return res; | ||||||
|             } catch (trap_access &ta) { |             } catch (trap_access &ta) { | ||||||
|                 this->reg.trap_state = (1 << 31) | ta.id; |                 this->reg.trap_state = (1 << 31) | ta.id; | ||||||
|  |                 fault_data=ta.addr; | ||||||
|                 return iss::Err; |                 return iss::Err; | ||||||
|             } |             } | ||||||
|  |  | ||||||
| @@ -545,6 +584,7 @@ iss::status riscv_hart_m_p<BASE>::write(const address_type type, const access_ty | |||||||
|         return iss::Ok; |         return iss::Ok; | ||||||
|     } catch (trap_access &ta) { |     } catch (trap_access &ta) { | ||||||
|         this->reg.trap_state = (1 << 31) | ta.id; |         this->reg.trap_state = (1 << 31) | ta.id; | ||||||
|  |         fault_data=ta.addr; | ||||||
|         return iss::Err; |         return iss::Err; | ||||||
|     } |     } | ||||||
| } | } | ||||||
| @@ -670,7 +710,7 @@ template <typename BASE> iss::status riscv_hart_m_p<BASE>::write_status(unsigned | |||||||
|  |  | ||||||
| template <typename BASE> iss::status riscv_hart_m_p<BASE>::read_ie(unsigned addr, reg_t &val) { | template <typename BASE> iss::status riscv_hart_m_p<BASE>::read_ie(unsigned addr, reg_t &val) { | ||||||
|     val = csr[mie]; |     val = csr[mie]; | ||||||
|     val &= csr[mideleg]; |     //val &= csr[mideleg]; | ||||||
|     return iss::Ok; |     return iss::Ok; | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -688,7 +728,7 @@ template <typename BASE> iss::status riscv_hart_m_p<BASE>::write_ie(unsigned add | |||||||
|  |  | ||||||
| template <typename BASE> iss::status riscv_hart_m_p<BASE>::read_ip(unsigned addr, reg_t &val) { | template <typename BASE> iss::status riscv_hart_m_p<BASE>::read_ip(unsigned addr, reg_t &val) { | ||||||
|     val = csr[mip]; |     val = csr[mip]; | ||||||
|     val &= csr[mideleg]; |     //val &= csr[mideleg]; | ||||||
|     return iss::Ok; |     return iss::Ok; | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -727,7 +767,6 @@ iss::status riscv_hart_m_p<BASE>::read_mem(phys_addr_t paddr, unsigned length, u | |||||||
|  |  | ||||||
| template <typename BASE> | template <typename BASE> | ||||||
| iss::status riscv_hart_m_p<BASE>::write_mem(phys_addr_t paddr, unsigned length, const uint8_t *const data) { | iss::status riscv_hart_m_p<BASE>::write_mem(phys_addr_t paddr, unsigned length, const uint8_t *const data) { | ||||||
|     if ((paddr.val + length) > mem.size()) return iss::Err; |  | ||||||
|     if(mem_write_cb) return mem_write_cb(paddr, length, data); |     if(mem_write_cb) return mem_write_cb(paddr, length, data); | ||||||
|     switch (paddr.val) { |     switch (paddr.val) { | ||||||
|     case 0x10013000: // UART0 base, TXFIFO reg |     case 0x10013000: // UART0 base, TXFIFO reg | ||||||
| @@ -808,7 +847,7 @@ template <typename BASE> inline void riscv_hart_m_p<BASE>::reset(uint64_t addres | |||||||
| } | } | ||||||
|  |  | ||||||
| template <typename BASE> void riscv_hart_m_p<BASE>::check_interrupt() { | template <typename BASE> void riscv_hart_m_p<BASE>::check_interrupt() { | ||||||
|     auto ideleg = csr[mideleg]; |     //auto ideleg = csr[mideleg]; | ||||||
|     // Multiple simultaneous interrupts and traps at the same privilege level are |     // Multiple simultaneous interrupts and traps at the same privilege level are | ||||||
|     // handled in the following decreasing priority order: |     // handled in the following decreasing priority order: | ||||||
|     // external interrupts, software interrupts, timer interrupts, then finally |     // external interrupts, software interrupts, timer interrupts, then finally | ||||||
| @@ -817,7 +856,7 @@ template <typename BASE> void riscv_hart_m_p<BASE>::check_interrupt() { | |||||||
|  |  | ||||||
|     bool mie = state.mstatus.MIE; |     bool mie = state.mstatus.MIE; | ||||||
|     auto m_enabled = this->reg.PRIV < PRIV_M || (this->reg.PRIV == PRIV_M && mie); |     auto m_enabled = this->reg.PRIV < PRIV_M || (this->reg.PRIV == PRIV_M && mie); | ||||||
|     auto enabled_interrupts = m_enabled ? ena_irq & ~ideleg : 0; |     auto enabled_interrupts = m_enabled ? ena_irq /*& ~ideleg*/ : 0; | ||||||
|  |  | ||||||
|     if (enabled_interrupts != 0) { |     if (enabled_interrupts != 0) { | ||||||
|         int res = 0; |         int res = 0; | ||||||
| @@ -839,7 +878,7 @@ template <typename BASE> uint64_t riscv_hart_m_p<BASE>::enter_trap(uint64_t flag | |||||||
|     if (trap_id == 0) { // exception |     if (trap_id == 0) { // exception | ||||||
|         // store ret addr in xepc register |         // store ret addr in xepc register | ||||||
|         csr[mepc] = static_cast<reg_t>(addr); // store actual address instruction of exception |         csr[mepc] = static_cast<reg_t>(addr); // store actual address instruction of exception | ||||||
|         csr[mtval] = cause==2?instr:fault_data; |         csr[mtval] = cause==2?((instr & 0x3)==3?instr:instr&0xffff):fault_data; | ||||||
|         fault_data = 0; |         fault_data = 0; | ||||||
|     } else { |     } else { | ||||||
|         csr[mepc] = this->reg.NEXT_PC; // store next address if interrupt |         csr[mepc] = this->reg.NEXT_PC; // store next address if interrupt | ||||||
| @@ -877,9 +916,11 @@ template <typename BASE> uint64_t riscv_hart_m_p<BASE>::enter_trap(uint64_t flag | |||||||
|  |  | ||||||
| template <typename BASE> uint64_t riscv_hart_m_p<BASE>::leave_trap(uint64_t flags) { | template <typename BASE> uint64_t riscv_hart_m_p<BASE>::leave_trap(uint64_t flags) { | ||||||
|     state.mstatus.MIE = state.mstatus.MPIE; |     state.mstatus.MIE = state.mstatus.MPIE; | ||||||
|  |     state.mstatus.MPIE = 1; | ||||||
|     // sets the pc to the value stored in the x epc register. |     // sets the pc to the value stored in the x epc register. | ||||||
|     this->reg.NEXT_PC = csr[mepc]; |     this->reg.NEXT_PC = csr[mepc]; | ||||||
|     CLOG(INFO, disass) << "Executing xRET"; |     CLOG(INFO, disass) << "Executing xRET"; | ||||||
|  |     check_interrupt(); | ||||||
|     return this->reg.NEXT_PC; |     return this->reg.NEXT_PC; | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1228,15 +1228,18 @@ template <typename BASE> uint64_t riscv_hart_msu_vp<BASE>::leave_trap(uint64_t f | |||||||
|         this->reg.PRIV = state.mstatus.MPP; |         this->reg.PRIV = state.mstatus.MPP; | ||||||
|         state.mstatus.MPP = 0; // clear mpp to U mode |         state.mstatus.MPP = 0; // clear mpp to U mode | ||||||
|         state.mstatus.MIE = state.mstatus.MPIE; |         state.mstatus.MIE = state.mstatus.MPIE; | ||||||
|  |         state.mstatus.MPIE = 1; | ||||||
|         break; |         break; | ||||||
|     case PRIV_S: |     case PRIV_S: | ||||||
|         this->reg.PRIV = state.mstatus.SPP; |         this->reg.PRIV = state.mstatus.SPP; | ||||||
|         state.mstatus.SPP = 0; // clear spp to U mode |         state.mstatus.SPP = 0; // clear spp to U mode | ||||||
|         state.mstatus.SIE = state.mstatus.SPIE; |         state.mstatus.SIE = state.mstatus.SPIE; | ||||||
|  |         state.mstatus.SPIE = 1; | ||||||
|         break; |         break; | ||||||
|     case PRIV_U: |     case PRIV_U: | ||||||
|         this->reg.PRIV = 0; |         this->reg.PRIV = 0; | ||||||
|         state.mstatus.UIE = state.mstatus.UPIE; |         state.mstatus.UIE = state.mstatus.UPIE; | ||||||
|  |         state.mstatus.UPIE = 1; | ||||||
|         break; |         break; | ||||||
|     } |     } | ||||||
|     // sets the pc to the value stored in the x epc register. |     // sets the pc to the value stored in the x epc register. | ||||||
| @@ -1244,6 +1247,7 @@ template <typename BASE> uint64_t riscv_hart_msu_vp<BASE>::leave_trap(uint64_t f | |||||||
|     CLOG(INFO, disass) << "Executing xRET , changing privilege level from " << lvl[cur_priv] << " to " |     CLOG(INFO, disass) << "Executing xRET , changing privilege level from " << lvl[cur_priv] << " to " | ||||||
|                        << lvl[this->reg.PRIV]; |                        << lvl[this->reg.PRIV]; | ||||||
|     update_vm_info(); |     update_vm_info(); | ||||||
|  |     check_interrupt(); | ||||||
|     return this->reg.NEXT_PC; |     return this->reg.NEXT_PC; | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -870,16 +870,19 @@ template <typename BASE, features_e FEAT> uint64_t riscv_hart_mu_p<BASE, FEAT>:: | |||||||
|         this->reg.PRIV = state.mstatus.MPP; |         this->reg.PRIV = state.mstatus.MPP; | ||||||
|         state.mstatus.MPP = 0; // clear mpp to U mode |         state.mstatus.MPP = 0; // clear mpp to U mode | ||||||
|         state.mstatus.MIE = state.mstatus.MPIE; |         state.mstatus.MIE = state.mstatus.MPIE; | ||||||
|  |         state.mstatus.MPIE = 1; | ||||||
|         break; |         break; | ||||||
|     case PRIV_U: |     case PRIV_U: | ||||||
|         this->reg.PRIV = 0; |         this->reg.PRIV = 0; | ||||||
|         state.mstatus.UIE = state.mstatus.UPIE; |         state.mstatus.UIE = state.mstatus.UPIE; | ||||||
|  |         state.mstatus.UPIE = 1; | ||||||
|         break; |         break; | ||||||
|     } |     } | ||||||
|     // sets the pc to the value stored in the x epc register. |     // sets the pc to the value stored in the x epc register. | ||||||
|     this->reg.NEXT_PC = csr[uepc | inst_priv << 8]; |     this->reg.NEXT_PC = csr[uepc | inst_priv << 8]; | ||||||
|     CLOG(INFO, disass) << "Executing xRET , changing privilege level from " << lvl[cur_priv] << " to " |     CLOG(INFO, disass) << "Executing xRET , changing privilege level from " << lvl[cur_priv] << " to " | ||||||
|                        << lvl[this->reg.PRIV]; |                        << lvl[this->reg.PRIV]; | ||||||
|  |     check_interrupt(); | ||||||
|     return this->reg.NEXT_PC; |     return this->reg.NEXT_PC; | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -53,7 +53,7 @@ template <> struct traits<tgc_c> { | |||||||
|     static constexpr std::array<const char*, 35> reg_aliases{ |     static constexpr std::array<const char*, 35> reg_aliases{ | ||||||
|         {"X0", "X1", "X2", "X3", "X4", "X5", "X6", "X7", "X8", "X9", "X10", "X11", "X12", "X13", "X14", "X15", "X16", "X17", "X18", "X19", "X20", "X21", "X22", "X23", "X24", "X25", "X26", "X27", "X28", "X29", "X30", "X31", "PC", "NEXT_PC", "PRIV"}}; |         {"X0", "X1", "X2", "X3", "X4", "X5", "X6", "X7", "X8", "X9", "X10", "X11", "X12", "X13", "X14", "X15", "X16", "X17", "X18", "X19", "X20", "X21", "X22", "X23", "X24", "X25", "X26", "X27", "X28", "X29", "X30", "X31", "PC", "NEXT_PC", "PRIV"}}; | ||||||
|  |  | ||||||
|     enum constants {XLEN=32, PCLEN=32, MISA_VAL=0b01000000000000000001000100000100, PGSIZE=0x1000, PGMASK=0b111111111111, CSR_SIZE=4096, fence=0, fencei=1, fencevmal=2, fencevmau=3, eei_aligned_addresses=1, MUL_LEN=64}; |     enum constants {XLEN=32, PCLEN=32, MISA_VAL=0b01000000000000000001000100000100, PGSIZE=0x1000, PGMASK=0b111111111111, CSR_SIZE=4096, fence=0, fencei=1, fencevmal=2, fencevmau=3, MUL_LEN=64}; | ||||||
|  |  | ||||||
|     constexpr static unsigned FP_REGS_SIZE = 0; |     constexpr static unsigned FP_REGS_SIZE = 0; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -875,11 +875,8 @@ private: | |||||||
|         try { |         try { | ||||||
|         { |         { | ||||||
|             uint32_t load_address = *(X+rs1) + (int16_t)sext<12>(imm); |             uint32_t load_address = *(X+rs1) + (int16_t)sext<12>(imm); | ||||||
|             if(traits::eei_aligned_addresses && (load_address & 0x1)) raise(0,  4);  |             int16_t res = (int16_t)readSpace2(traits::MEM, *(X+rs1) + (int16_t)sext<12>(imm)); | ||||||
|             else { |             if(rd != 0) *(X+rd) = res;  | ||||||
|                 int16_t res = (int16_t)readSpace2(traits::MEM, *(X+rs1) + (int16_t)sext<12>(imm)); |  | ||||||
|                 if(rd != 0) *(X+rd) = res;  |  | ||||||
|             } |  | ||||||
|         } |         } | ||||||
|         } catch(...){} |         } catch(...){} | ||||||
|         // post execution stuff |         // post execution stuff | ||||||
| @@ -923,11 +920,8 @@ private: | |||||||
|         try { |         try { | ||||||
|         { |         { | ||||||
|             uint32_t load_address = *(X+rs1) + (int16_t)sext<12>(imm); |             uint32_t load_address = *(X+rs1) + (int16_t)sext<12>(imm); | ||||||
|             if(traits::eei_aligned_addresses && (load_address & 0x3)) raise(0,  4);  |             int32_t res = (int32_t)readSpace4(traits::MEM, *(X+rs1) + (int16_t)sext<12>(imm)); | ||||||
|             else { |             if(rd != 0) *(X+rd) = (uint32_t)res;  | ||||||
|                 int32_t res = (int32_t)readSpace4(traits::MEM, *(X+rs1) + (int16_t)sext<12>(imm)); |  | ||||||
|                 if(rd != 0) *(X+rd) = (uint32_t)res;  |  | ||||||
|             } |  | ||||||
|         } |         } | ||||||
|         } catch(...){} |         } catch(...){} | ||||||
|         // post execution stuff |         // post execution stuff | ||||||
| @@ -1015,11 +1009,8 @@ private: | |||||||
|         try { |         try { | ||||||
|         { |         { | ||||||
|             uint32_t load_address = *(X+rs1) + (int16_t)sext<12>(imm); |             uint32_t load_address = *(X+rs1) + (int16_t)sext<12>(imm); | ||||||
|             if(traits::eei_aligned_addresses && (load_address & 0x1)) raise(0,  4);  |             uint16_t res = (uint16_t)readSpace2(traits::MEM, *(X+rs1) + (int16_t)sext<12>(imm)); | ||||||
|             else { |             if(rd != 0) *(X+rd) = res;  | ||||||
|                 uint16_t res = (uint16_t)readSpace2(traits::MEM, *(X+rs1) + (int16_t)sext<12>(imm)); |  | ||||||
|                 if(rd != 0) *(X+rd) = res;  |  | ||||||
|             } |  | ||||||
|         } |         } | ||||||
|         } catch(...){} |         } catch(...){} | ||||||
|         // post execution stuff |         // post execution stuff | ||||||
| @@ -1104,8 +1095,7 @@ private: | |||||||
|         try { |         try { | ||||||
|         { |         { | ||||||
|             uint32_t store_address = *(X+rs1) + (int16_t)sext<12>(imm); |             uint32_t store_address = *(X+rs1) + (int16_t)sext<12>(imm); | ||||||
|             if(traits::eei_aligned_addresses && (store_address & 0x1)) raise(0,  6);  |             writeSpace2(traits::MEM, store_address, (int16_t)*(X+rs2)); | ||||||
|             else writeSpace2(traits::MEM, store_address, (int16_t)*(X+rs2)); |  | ||||||
|         } |         } | ||||||
|         } catch(...){} |         } catch(...){} | ||||||
|         // post execution stuff |         // post execution stuff | ||||||
| @@ -1149,8 +1139,7 @@ private: | |||||||
|         try { |         try { | ||||||
|         { |         { | ||||||
|             uint32_t store_address = *(X+rs1) + (int16_t)sext<12>(imm); |             uint32_t store_address = *(X+rs1) + (int16_t)sext<12>(imm); | ||||||
|             if(traits::eei_aligned_addresses && (store_address & 0x3)) raise(0,  6);  |             writeSpace4(traits::MEM, store_address, *(X+rs2)); | ||||||
|             else writeSpace4(traits::MEM, store_address, *(X+rs2)); |  | ||||||
|         } |         } | ||||||
|         } catch(...){} |         } catch(...){} | ||||||
|         // post execution stuff |         // post execution stuff | ||||||
| @@ -2929,8 +2918,7 @@ private: | |||||||
|         try { |         try { | ||||||
|         { |         { | ||||||
|             uint32_t load_address = *(X+(rs1 + 8)) + uimm; |             uint32_t load_address = *(X+(rs1 + 8)) + uimm; | ||||||
|             if(traits::eei_aligned_addresses && (load_address & 0x3)) raise(0,  4);  |             *(X+(rd + 8)) = (int32_t)readSpace4(traits::MEM, load_address); | ||||||
|             else *(X+(rd + 8)) = (int32_t)readSpace4(traits::MEM, load_address); |  | ||||||
|         } |         } | ||||||
|         } catch(...){} |         } catch(...){} | ||||||
|         // post execution stuff |         // post execution stuff | ||||||
| @@ -2974,8 +2962,7 @@ private: | |||||||
|         try { |         try { | ||||||
|         { |         { | ||||||
|             uint32_t load_address = *(X+(rs1 + 8)) + uimm; |             uint32_t load_address = *(X+(rs1 + 8)) + uimm; | ||||||
|             if(traits::eei_aligned_addresses && (load_address & 0x3)) raise(0,  6);  |             writeSpace4(traits::MEM, load_address, *(X+(rs2 + 8))); | ||||||
|             else writeSpace4(traits::MEM, load_address, *(X+(rs2 + 8))); |  | ||||||
|         } |         } | ||||||
|         } catch(...){} |         } catch(...){} | ||||||
|         // post execution stuff |         // post execution stuff | ||||||
| @@ -3759,8 +3746,7 @@ private: | |||||||
|         try { |         try { | ||||||
|         if(rd) { |         if(rd) { | ||||||
|             uint32_t offs = *(X+2) + uimm; |             uint32_t offs = *(X+2) + uimm; | ||||||
|             if(traits::eei_aligned_addresses && (offs & 0x3)) raise(0,  4);  |             *(X+rd) = (int32_t)readSpace4(traits::MEM, offs); | ||||||
|             else *(X+rd) = (int32_t)readSpace4(traits::MEM, offs); |  | ||||||
|         } |         } | ||||||
|         else raise(0, 2); |         else raise(0, 2); | ||||||
|         } catch(...){} |         } catch(...){} | ||||||
| @@ -4035,8 +4021,7 @@ private: | |||||||
|         try { |         try { | ||||||
|         { |         { | ||||||
|             uint32_t offs = *(X+2) + uimm; |             uint32_t offs = *(X+2) + uimm; | ||||||
|             if(traits::eei_aligned_addresses && (offs & 0x3)) raise(0,  4);  |             writeSpace4(traits::MEM, offs, (uint32_t)*(X+rs2)); | ||||||
|             else writeSpace4(traits::MEM, offs, (uint32_t)*(X+rs2)); |  | ||||||
|         } |         } | ||||||
|         } catch(...){} |         } catch(...){} | ||||||
|         // post execution stuff |         // post execution stuff | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user