Adapted generated code to support translation block linking

This commit is contained in:
2018-05-15 18:49:29 +02:00
parent 5b6dc36c9d
commit dfcc3ace66
17 changed files with 353 additions and 93 deletions

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;