Adapted generated code to support translation block linking
This commit is contained in:
		| @@ -50,6 +50,9 @@ | ||||
| #include <array> | ||||
| #include <type_traits> | ||||
|  | ||||
| #define likely(x)       __builtin_expect(!!(x), 1) | ||||
| #define unlikely(x)     __builtin_expect(!!(x), 0) | ||||
|  | ||||
| namespace iss { | ||||
| namespace arch { | ||||
|  | ||||
| @@ -647,14 +650,14 @@ iss::status riscv_hart_msu_vp<BASE>::read(const iss::addr_t &addr, unsigned leng | ||||
|     try { | ||||
|         switch (addr.space) { | ||||
|         case traits<BASE>::MEM: { | ||||
|             if ((addr.access == iss::access_type::FETCH || addr.access == iss::access_type::DEBUG_FETCH) && (addr.val & 0x1) == 1) { | ||||
|             if (unlikely((addr.access == iss::access_type::FETCH || addr.access == iss::access_type::DEBUG_FETCH) && (addr.val & 0x1) == 1)) { | ||||
|                 fault_data = addr.val; | ||||
|                 if (addr.access && iss::access_type::DEBUG) throw trap_access(0, addr.val); | ||||
|                 this->reg.trap_state = (1 << 31); // issue trap 0 | ||||
|                 return iss::Err; | ||||
|             } | ||||
|             try { | ||||
|                 if ((addr.val & ~PGMASK) != ((addr.val + length - 1) & ~PGMASK)) { // we may cross a page boundary | ||||
|                 if (unlikely((addr.val & ~PGMASK) != ((addr.val + length - 1) & ~PGMASK))) { // we may cross a page boundary | ||||
|                     vm_info vm = hart_state<reg_t>::decode_vm_info(this->reg.machine_state, state.satp); | ||||
|                     if (vm.levels != 0) { // VM is active | ||||
|                         auto split_addr = (addr.val + length) & ~PGMASK; | ||||
| @@ -666,7 +669,7 @@ iss::status riscv_hart_msu_vp<BASE>::read(const iss::addr_t &addr, unsigned leng | ||||
|                     } | ||||
|                 } | ||||
|                 auto res = read_mem( BASE::v2p(addr), length, data); | ||||
|                 if (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 | ||||
|                 return res; | ||||
|             } catch (trap_access &ta) { | ||||
|                 this->reg.trap_state = (1 << 31) | ta.id; | ||||
| @@ -738,14 +741,14 @@ iss::status riscv_hart_msu_vp<BASE>::write(const iss::addr_t &addr, unsigned len | ||||
|     try { | ||||
|         switch (addr.space) { | ||||
|         case traits<BASE>::MEM: { | ||||
|             if ((addr.access && iss::access_type::FETCH) && (addr.val & 0x1) == 1) { | ||||
|             if (unlikely((addr.access && iss::access_type::FETCH) && (addr.val & 0x1) == 1)) { | ||||
|                 fault_data = addr.val; | ||||
|                 if (addr.access && iss::access_type::DEBUG) throw trap_access(0, addr.val); | ||||
|                 this->reg.trap_state = (1 << 31); // issue trap 0 | ||||
|                 return iss::Err; | ||||
|             } | ||||
|             try { | ||||
|                 if ((addr.val & ~PGMASK) != ((addr.val + length - 1) & ~PGMASK)) { // we may cross a page boundary | ||||
|                 if (unlikely((addr.val & ~PGMASK) != ((addr.val + length - 1) & ~PGMASK))) { // we may cross a page boundary | ||||
|                     vm_info vm = hart_state<reg_t>::decode_vm_info(this->reg.machine_state, state.satp); | ||||
|                     if (vm.levels != 0) { // VM is active | ||||
|                         auto split_addr = (addr.val + length) & ~PGMASK; | ||||
| @@ -757,7 +760,7 @@ iss::status riscv_hart_msu_vp<BASE>::write(const iss::addr_t &addr, unsigned len | ||||
|                     } | ||||
|                 } | ||||
|                 auto res = write_mem(BASE::v2p(addr), length, data); | ||||
|                 if (res != iss::Ok) this->reg.trap_state = (1 << 31) | (5 << 16); // issue trap 7 (Store/AMO access fault) | ||||
|                 if (unlikely(res != iss::Ok)) this->reg.trap_state = (1 << 31) | (5 << 16); // issue trap 7 (Store/AMO access fault) | ||||
|                 return res; | ||||
|             } catch (trap_access &ta) { | ||||
|                 this->reg.trap_state = (1 << 31) | ta.id; | ||||
|   | ||||
| @@ -124,6 +124,7 @@ struct traits<rv32gc> { | ||||
|         TRAP_STATE, | ||||
|         PENDING_TRAP, | ||||
|         MACHINE_STATE, | ||||
|         LAST_BRANCH, | ||||
|         ICOUNT | ||||
|     }; | ||||
|  | ||||
| @@ -138,12 +139,12 @@ struct traits<rv32gc> { | ||||
|     using phys_addr_t = iss::typed_addr_t<iss::address_type::PHYSICAL>; | ||||
|  | ||||
|     constexpr static unsigned reg_bit_width(unsigned r) { | ||||
|         constexpr std::array<const uint32_t, 71> RV32GC_reg_size{{32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,32,32,32,32,32,64}}; | ||||
|         constexpr std::array<const uint32_t, 72> RV32GC_reg_size{{32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,32,32,32,32,32,32,64}}; | ||||
|         return RV32GC_reg_size[r]; | ||||
|     } | ||||
|  | ||||
|     constexpr static unsigned reg_byte_offset(unsigned r) { | ||||
|     	constexpr std::array<const uint32_t, 72> RV32GC_reg_byte_offset{{0,4,8,12,16,20,24,28,32,36,40,44,48,52,56,60,64,68,72,76,80,84,88,92,96,100,104,108,112,116,120,124,128,136,144,152,160,168,176,184,192,200,208,216,224,232,240,248,256,264,272,280,288,296,304,312,320,328,336,344,352,360,368,376,384,392,396,400,404,408,416,424}}; | ||||
|     	constexpr std::array<const uint32_t, 73> RV32GC_reg_byte_offset{{0,4,8,12,16,20,24,28,32,36,40,44,48,52,56,60,64,68,72,76,80,84,88,92,96,100,104,108,112,116,120,124,128,136,144,152,160,168,176,184,192,200,208,216,224,232,240,248,256,264,272,280,288,296,304,312,320,328,336,344,352,360,368,376,384,392,396,400,404,408,412,416,424}}; | ||||
|         return RV32GC_reg_byte_offset[r]; | ||||
|     } | ||||
|  | ||||
| @@ -191,6 +192,9 @@ struct rv32gc: public arch_if { | ||||
|  | ||||
|     virtual iss::sync_type needed_sync() const { return iss::NO_SYNC; } | ||||
|  | ||||
|     inline | ||||
|     uint32_t get_last_branch(){return reg.last_branch;} | ||||
|  | ||||
| protected: | ||||
|     struct RV32GC_regs { | ||||
|         uint32_t X0 = 0; | ||||
| @@ -260,7 +264,7 @@ protected: | ||||
|         uint64_t F31 = 0; | ||||
|         uint32_t FCSR = 0; | ||||
|         uint32_t NEXT_PC = 0; | ||||
|         uint32_t trap_state = 0, pending_trap = 0, machine_state = 0; | ||||
|         uint32_t trap_state = 0, pending_trap = 0, machine_state = 0, last_branch = 0; | ||||
|         uint64_t icount = 0; | ||||
|     } reg; | ||||
|  | ||||
|   | ||||
| @@ -91,6 +91,7 @@ struct traits<rv32imac> { | ||||
|         TRAP_STATE, | ||||
|         PENDING_TRAP, | ||||
|         MACHINE_STATE, | ||||
|         LAST_BRANCH, | ||||
|         ICOUNT | ||||
|     }; | ||||
|  | ||||
| @@ -105,12 +106,12 @@ struct traits<rv32imac> { | ||||
|     using phys_addr_t = iss::typed_addr_t<iss::address_type::PHYSICAL>; | ||||
|  | ||||
|     constexpr static unsigned reg_bit_width(unsigned r) { | ||||
|         constexpr std::array<const uint32_t, 38> RV32IMAC_reg_size{{32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,64}}; | ||||
|         constexpr std::array<const uint32_t, 39> RV32IMAC_reg_size{{32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,64}}; | ||||
|         return RV32IMAC_reg_size[r]; | ||||
|     } | ||||
|  | ||||
|     constexpr static unsigned reg_byte_offset(unsigned r) { | ||||
|     	constexpr std::array<const uint32_t, 39> RV32IMAC_reg_byte_offset{{0,4,8,12,16,20,24,28,32,36,40,44,48,52,56,60,64,68,72,76,80,84,88,92,96,100,104,108,112,116,120,124,128,132,136,140,144,152,160}}; | ||||
|     	constexpr std::array<const uint32_t, 40> RV32IMAC_reg_byte_offset{{0,4,8,12,16,20,24,28,32,36,40,44,48,52,56,60,64,68,72,76,80,84,88,92,96,100,104,108,112,116,120,124,128,132,136,140,144,148,152,160}}; | ||||
|         return RV32IMAC_reg_byte_offset[r]; | ||||
|     } | ||||
|  | ||||
| @@ -158,6 +159,9 @@ struct rv32imac: public arch_if { | ||||
|  | ||||
|     virtual iss::sync_type needed_sync() const { return iss::NO_SYNC; } | ||||
|  | ||||
|     inline | ||||
|     uint32_t get_last_branch(){return reg.last_branch;} | ||||
|  | ||||
| protected: | ||||
|     struct RV32IMAC_regs { | ||||
|         uint32_t X0 = 0; | ||||
| @@ -194,7 +198,7 @@ protected: | ||||
|         uint32_t X31 = 0; | ||||
|         uint32_t PC = 0; | ||||
|         uint32_t NEXT_PC = 0; | ||||
|         uint32_t trap_state = 0, pending_trap = 0, machine_state = 0; | ||||
|         uint32_t trap_state = 0, pending_trap = 0, machine_state = 0, last_branch = 0; | ||||
|         uint64_t icount = 0; | ||||
|     } reg; | ||||
|  | ||||
|   | ||||
| @@ -91,6 +91,7 @@ struct traits<rv64ia> { | ||||
|         TRAP_STATE, | ||||
|         PENDING_TRAP, | ||||
|         MACHINE_STATE, | ||||
|         LAST_BRANCH, | ||||
|         ICOUNT | ||||
|     }; | ||||
|  | ||||
| @@ -105,12 +106,12 @@ struct traits<rv64ia> { | ||||
|     using phys_addr_t = iss::typed_addr_t<iss::address_type::PHYSICAL>; | ||||
|  | ||||
|     constexpr static unsigned reg_bit_width(unsigned r) { | ||||
|         constexpr std::array<const uint32_t, 38> RV64IA_reg_size{{64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,32,32,32,64}}; | ||||
|         constexpr std::array<const uint32_t, 39> RV64IA_reg_size{{64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,32,32,32,32,64}}; | ||||
|         return RV64IA_reg_size[r]; | ||||
|     } | ||||
|  | ||||
|     constexpr static unsigned reg_byte_offset(unsigned r) { | ||||
|     	constexpr std::array<const uint32_t, 39> RV64IA_reg_byte_offset{{0,8,16,24,32,40,48,56,64,72,80,88,96,104,112,120,128,136,144,152,160,168,176,184,192,200,208,216,224,232,240,248,256,264,272,276,280,288,296}}; | ||||
|     	constexpr std::array<const uint32_t, 40> RV64IA_reg_byte_offset{{0,8,16,24,32,40,48,56,64,72,80,88,96,104,112,120,128,136,144,152,160,168,176,184,192,200,208,216,224,232,240,248,256,264,272,276,280,284,288,296}}; | ||||
|         return RV64IA_reg_byte_offset[r]; | ||||
|     } | ||||
|  | ||||
| @@ -158,6 +159,9 @@ struct rv64ia: public arch_if { | ||||
|  | ||||
|     virtual iss::sync_type needed_sync() const { return iss::NO_SYNC; } | ||||
|  | ||||
|     inline | ||||
|     uint32_t get_last_branch(){return reg.last_branch;} | ||||
|  | ||||
| protected: | ||||
|     struct RV64IA_regs { | ||||
|         uint64_t X0 = 0; | ||||
| @@ -194,7 +198,7 @@ protected: | ||||
|         uint64_t X31 = 0; | ||||
|         uint64_t PC = 0; | ||||
|         uint64_t NEXT_PC = 0; | ||||
|         uint32_t trap_state = 0, pending_trap = 0, machine_state = 0; | ||||
|         uint32_t trap_state = 0, pending_trap = 0, machine_state = 0, last_branch = 0; | ||||
|         uint64_t icount = 0; | ||||
|     } reg; | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user