fixes duplicate variable declaration and templates
This commit is contained in:
@ -280,7 +280,7 @@ public:
|
||||
|
||||
void disass_output(uint64_t pc, const std::string instr) override {
|
||||
CLOG(INFO, disass) << fmt::format("0x{:016x} {:40} [s:0x{:x};c:{}]",
|
||||
pc, instr, (reg_t)state.mstatus, this->icount + cycle_offset);
|
||||
pc, instr, (reg_t)state.mstatus, this->reg.icount + cycle_offset);
|
||||
};
|
||||
|
||||
iss::instrumentation_if *get_instrumentation_if() override { return &instr_if; }
|
||||
@ -308,17 +308,17 @@ protected:
|
||||
|
||||
uint64_t get_next_pc() override { return arch.reg.NEXT_PC; };
|
||||
|
||||
uint64_t get_instr_word() override { return arch.instruction; }
|
||||
uint64_t get_instr_word() override { return arch.reg.instruction; }
|
||||
|
||||
uint64_t get_instr_count() override { return arch.icount; }
|
||||
uint64_t get_instr_count() override { return arch.reg.icount; }
|
||||
|
||||
uint64_t get_pendig_traps() override { return arch.trap_state; }
|
||||
uint64_t get_pendig_traps() override { return arch.reg.trap_state; }
|
||||
|
||||
uint64_t get_total_cycles() override { return arch.icount + arch.cycle_offset; }
|
||||
uint64_t get_total_cycles() override { return arch.reg.icount + arch.cycle_offset; }
|
||||
|
||||
void update_last_instr_cycles(unsigned cycles) override { arch.cycle_offset += cycles - 1; };
|
||||
|
||||
bool is_branch_taken() override { return arch.last_branch; };
|
||||
bool is_branch_taken() override { return arch.reg.last_branch; };
|
||||
|
||||
riscv_hart_m_p<BASE, FEAT> &arch;
|
||||
};
|
||||
@ -657,12 +657,12 @@ iss::status riscv_hart_m_p<BASE, FEAT>::read(const address_type type, const acce
|
||||
if (unlikely(is_fetch(access) && (addr&(alignment-1)))) {
|
||||
fault_data = addr;
|
||||
if (is_debug(access)) throw trap_access(0, addr);
|
||||
this->trap_state = (1UL << 31); // issue trap 0
|
||||
this->reg.trap_state = (1UL << 31); // issue trap 0
|
||||
return iss::Err;
|
||||
}
|
||||
try {
|
||||
if(!is_debug(access) && (addr&(alignment-1))){
|
||||
this->trap_state = (1UL << 31) | 4<<16;
|
||||
this->reg.trap_state = (1UL << 31) | 4<<16;
|
||||
fault_data=addr;
|
||||
return iss::Err;
|
||||
}
|
||||
@ -681,12 +681,12 @@ iss::status riscv_hart_m_p<BASE, FEAT>::read(const address_type type, const acce
|
||||
res = hart_mem_rd_delegate( phys_addr, length, data);
|
||||
}
|
||||
if (unlikely(res != iss::Ok)){
|
||||
this->trap_state = (1UL << 31) | (5 << 16); // issue trap 5 (load access fault
|
||||
this->reg.trap_state = (1UL << 31) | (5 << 16); // issue trap 5 (load access fault
|
||||
fault_data=addr;
|
||||
}
|
||||
return res;
|
||||
} catch (trap_access &ta) {
|
||||
this->trap_state = (1UL << 31) | ta.id;
|
||||
this->reg.trap_state = (1UL << 31) | ta.id;
|
||||
fault_data=ta.addr;
|
||||
return iss::Err;
|
||||
}
|
||||
@ -712,7 +712,7 @@ iss::status riscv_hart_m_p<BASE, FEAT>::read(const address_type type, const acce
|
||||
}
|
||||
return iss::Ok;
|
||||
} catch (trap_access &ta) {
|
||||
this->trap_state = (1UL << 31) | ta.id;
|
||||
this->reg.trap_state = (1UL << 31) | ta.id;
|
||||
fault_data=ta.addr;
|
||||
return iss::Err;
|
||||
}
|
||||
@ -750,12 +750,12 @@ iss::status riscv_hart_m_p<BASE, FEAT>::write(const address_type type, const acc
|
||||
if (unlikely((access && iss::access_type::FETCH) && (addr & 0x1) == 1)) {
|
||||
fault_data = addr;
|
||||
if (access && iss::access_type::DEBUG) throw trap_access(0, addr);
|
||||
this->trap_state = (1UL << 31); // issue trap 0
|
||||
this->reg.trap_state = (1UL << 31); // issue trap 0
|
||||
return iss::Err;
|
||||
}
|
||||
try {
|
||||
if(length>1 && (addr&(length-1)) && (access&access_type::DEBUG) != access_type::DEBUG){
|
||||
this->trap_state = (1UL << 31) | 6<<16;
|
||||
this->reg.trap_state = (1UL << 31) | 6<<16;
|
||||
fault_data=addr;
|
||||
return iss::Err;
|
||||
}
|
||||
@ -774,12 +774,12 @@ iss::status riscv_hart_m_p<BASE, FEAT>::write(const address_type type, const acc
|
||||
res = write_mem( phys_addr, length, data);
|
||||
}
|
||||
if (unlikely(res != iss::Ok)) {
|
||||
this->trap_state = (1UL << 31) | (7 << 16); // issue trap 7 (Store/AMO access fault)
|
||||
this->reg.trap_state = (1UL << 31) | (7 << 16); // issue trap 7 (Store/AMO access fault)
|
||||
fault_data=addr;
|
||||
}
|
||||
return res;
|
||||
} catch (trap_access &ta) {
|
||||
this->trap_state = (1UL << 31) | ta.id;
|
||||
this->reg.trap_state = (1UL << 31) | ta.id;
|
||||
fault_data=ta.addr;
|
||||
return iss::Err;
|
||||
}
|
||||
@ -839,7 +839,7 @@ iss::status riscv_hart_m_p<BASE, FEAT>::write(const address_type type, const acc
|
||||
}
|
||||
return iss::Ok;
|
||||
} catch (trap_access &ta) {
|
||||
this->trap_state = (1UL << 31) | ta.id;
|
||||
this->reg.trap_state = (1UL << 31) | ta.id;
|
||||
fault_data=ta.addr;
|
||||
return iss::Err;
|
||||
}
|
||||
@ -885,7 +885,7 @@ template <typename BASE, features_e FEAT> iss::status riscv_hart_m_p<BASE, FEAT>
|
||||
}
|
||||
|
||||
template <typename BASE, features_e FEAT> iss::status riscv_hart_m_p<BASE, FEAT>::read_cycle(unsigned addr, reg_t &val) {
|
||||
auto cycle_val = this->icount + cycle_offset;
|
||||
auto cycle_val = this->reg.icount + cycle_offset;
|
||||
if (addr == mcycle) {
|
||||
val = static_cast<reg_t>(cycle_val);
|
||||
} else if (addr == mcycleh) {
|
||||
@ -904,35 +904,35 @@ template <typename BASE, features_e FEAT> iss::status riscv_hart_m_p<BASE, FEAT>
|
||||
mcycle_csr = (static_cast<uint64_t>(val)<<32) + (mcycle_csr & 0xffffffff);
|
||||
}
|
||||
}
|
||||
cycle_offset = mcycle_csr-this->icount; // TODO: relying on wrap-around
|
||||
cycle_offset = mcycle_csr-this->reg.icount; // TODO: relying on wrap-around
|
||||
return iss::Ok;
|
||||
}
|
||||
|
||||
template <typename BASE, features_e FEAT> iss::status riscv_hart_m_p<BASE, FEAT>::read_instret(unsigned addr, reg_t &val) {
|
||||
if ((addr&0xff) == (minstret&0xff)) {
|
||||
val = static_cast<reg_t>(this->instret);
|
||||
val = static_cast<reg_t>(this->reg.instret);
|
||||
} else if ((addr&0xff) == (minstreth&0xff)) {
|
||||
val = static_cast<reg_t>(this->instret >> 32);
|
||||
val = static_cast<reg_t>(this->reg.instret >> 32);
|
||||
}
|
||||
return iss::Ok;
|
||||
}
|
||||
|
||||
template <typename BASE, features_e FEAT> iss::status riscv_hart_m_p<BASE, FEAT>::write_instret(unsigned addr, reg_t val) {
|
||||
if (sizeof(typename traits<BASE>::reg_t) != 4) {
|
||||
this->instret = static_cast<uint64_t>(val);
|
||||
this->reg.instret = static_cast<uint64_t>(val);
|
||||
} else {
|
||||
if ((addr&0xff) == (minstret&0xff)) {
|
||||
this->instret = (this->instret & 0xffffffff00000000) + val;
|
||||
this->reg.instret = (this->reg.instret & 0xffffffff00000000) + val;
|
||||
} else {
|
||||
this->instret = (static_cast<uint64_t>(val)<<32) + (this->instret & 0xffffffff);
|
||||
this->reg.instret = (static_cast<uint64_t>(val)<<32) + (this->reg.instret & 0xffffffff);
|
||||
}
|
||||
}
|
||||
this->instret--;
|
||||
this->reg.instret--;
|
||||
return iss::Ok;
|
||||
}
|
||||
|
||||
template <typename BASE, features_e FEAT> iss::status riscv_hart_m_p<BASE, FEAT>::read_time(unsigned addr, reg_t &val) {
|
||||
uint64_t time_val = this->icount / (100000000 / 32768 - 1); //-> ~3052;
|
||||
uint64_t time_val = this->reg.icount / (100000000 / 32768 - 1); //-> ~3052;
|
||||
if (addr == time) {
|
||||
val = static_cast<reg_t>(time_val);
|
||||
} else if (addr == timeh) {
|
||||
@ -1074,18 +1074,6 @@ iss::status riscv_hart_m_p<BASE, FEAT>::write_xtvt(unsigned addr, reg_t val) {
|
||||
template <typename BASE, features_e FEAT>
|
||||
iss::status riscv_hart_m_p<BASE, FEAT>::read_mem(phys_addr_t paddr, unsigned length, uint8_t *const data) {
|
||||
switch (paddr.val) {
|
||||
case 0x0200BFF8: { // CLINT base, mtime reg
|
||||
if (sizeof(reg_t) < length) return iss::Err;
|
||||
reg_t time_val;
|
||||
this->read_csr(time, time_val);
|
||||
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);
|
||||
uint64_t offs = paddr.val & mem.page_addr_mask;
|
||||
std::copy(p.data() + offs, p.data() + offs + length, data);
|
||||
if (this->icount > 30000) data[3] |= 0x80;
|
||||
} break;
|
||||
default: {
|
||||
for(auto offs=0U; offs<length; ++offs) {
|
||||
*(data + offs)=mem[(paddr.val+offs)%mem.size()];
|
||||
@ -1098,29 +1086,13 @@ iss::status riscv_hart_m_p<BASE, FEAT>::read_mem(phys_addr_t paddr, unsigned len
|
||||
template <typename BASE, features_e FEAT>
|
||||
iss::status riscv_hart_m_p<BASE, FEAT>::write_mem(phys_addr_t paddr, unsigned length, const uint8_t *const data) {
|
||||
switch (paddr.val) {
|
||||
case 0x10013000: // UART0 base, TXFIFO reg
|
||||
case 0x10023000: // UART1 base, TXFIFO reg
|
||||
uart_buf << (char)data[0];
|
||||
case 0xFFFF0000: // UART0 base, TXFIFO reg
|
||||
if (((char)data[0]) == '\n' || data[0] == 0) {
|
||||
LOG(INFO)<<"UART"<<((paddr.val>>16)&0x3)<<" send '"<<uart_buf.str()<<"'";
|
||||
std::cout << uart_buf.str();
|
||||
LOG(INFO)<<"UART"<<((paddr.val>>12)&0x3)<<" send '"<<uart_buf.str()<<"'";
|
||||
uart_buf.str("");
|
||||
}
|
||||
} else if(((char)data[0]) != '\r')
|
||||
uart_buf << (char)data[0];
|
||||
break;
|
||||
case 0x10008000: { // HFROSC base, hfrosccfg reg
|
||||
mem_type::page_type &p = mem(paddr.val / mem.page_size);
|
||||
size_t offs = paddr.val & mem.page_addr_mask;
|
||||
std::copy(data, data + length, p.data() + offs);
|
||||
uint8_t &x = *(p.data() + offs + 3);
|
||||
if (x & 0x40) x |= 0x80; // hfroscrdy = 1 if hfroscen==1
|
||||
} break;
|
||||
case 0x10008008: { // HFROSC base, pllcfg reg
|
||||
mem_type::page_type &p = mem(paddr.val / mem.page_size);
|
||||
size_t offs = paddr.val & mem.page_addr_mask;
|
||||
std::copy(data, data + length, p.data() + offs);
|
||||
uint8_t &x = *(p.data() + offs + 3);
|
||||
x |= 0x80; // set pll lock upon writing
|
||||
} break;
|
||||
default: {
|
||||
mem_type::page_type &p = mem(paddr.val / mem.page_size);
|
||||
std::copy(data, data + length, p.data() + (paddr.val & mem.page_addr_mask));
|
||||
@ -1142,7 +1114,7 @@ iss::status riscv_hart_m_p<BASE, FEAT>::write_mem(phys_addr_t paddr, unsigned le
|
||||
LOG(INFO) << "tohost value is 0x" << std::hex << hostvar << std::dec << " (" << hostvar
|
||||
<< "), stopping simulation";
|
||||
}
|
||||
this->trap_state=std::numeric_limits<uint32_t>::max();
|
||||
this->reg.trap_state=std::numeric_limits<uint32_t>::max();
|
||||
this->interrupt_sim=hostvar;
|
||||
break;
|
||||
//throw(iss::simulation_stopped(hostvar));
|
||||
@ -1227,7 +1199,7 @@ template <typename BASE, features_e FEAT> void riscv_hart_m_p<BASE, FEAT>::check
|
||||
enabled_interrupts >>= 1;
|
||||
res++;
|
||||
}
|
||||
this->pending_trap = res << 16 | 1; // 0x80 << 24 | (cause << 16) | trap_id
|
||||
this->reg.pending_trap = res << 16 | 1; // 0x80 << 24 | (cause << 16) | trap_id
|
||||
}
|
||||
}
|
||||
|
||||
@ -1275,7 +1247,7 @@ template <typename BASE, features_e FEAT> uint64_t riscv_hart_m_p<BASE, FEAT>::e
|
||||
fault_data = 0;
|
||||
} else {
|
||||
csr[mepc] = this->reg.NEXT_PC & get_pc_mask(); // store next address if interrupt
|
||||
this->pending_trap = 0;
|
||||
this->reg.pending_trap = 0;
|
||||
}
|
||||
csr[mcause] = (trap_id << (traits<BASE>::XLEN-1)) + cause;
|
||||
// update mstatus
|
||||
@ -1305,7 +1277,7 @@ template <typename BASE, features_e FEAT> uint64_t riscv_hart_m_p<BASE, FEAT>::e
|
||||
}
|
||||
// reset trap state
|
||||
this->reg.PRIV = new_priv;
|
||||
this->trap_state = 0;
|
||||
this->reg.trap_state = 0;
|
||||
std::array<char, 32> buffer;
|
||||
#if defined(_MSC_VER)
|
||||
sprintf(buffer.data(), "0x%016llx", addr);
|
||||
@ -1326,7 +1298,7 @@ template <typename BASE, features_e FEAT> uint64_t riscv_hart_m_p<BASE, FEAT>::l
|
||||
this->reg.NEXT_PC = csr[mepc] & get_pc_mask();
|
||||
CLOG(INFO, disass) << "Executing xRET";
|
||||
check_interrupt();
|
||||
this->trap_state = this->pending_trap;
|
||||
this->reg.trap_state = this->reg.pending_trap;
|
||||
return this->reg.NEXT_PC;
|
||||
}
|
||||
|
||||
|
@ -307,7 +307,7 @@ public:
|
||||
|
||||
void disass_output(uint64_t pc, const std::string instr) override {
|
||||
CLOG(INFO, disass) << fmt::format("0x{:016x} {:40} [p:{};s:0x{:x};c:{}]",
|
||||
pc, instr, lvl[this->reg.PRIV], (reg_t)state.mstatus, this->icount + cycle_offset);
|
||||
pc, instr, lvl[this->reg.PRIV], (reg_t)state.mstatus, this->reg.icount + cycle_offset);
|
||||
};
|
||||
|
||||
iss::instrumentation_if *get_instrumentation_if() override { return &instr_if; }
|
||||
@ -607,12 +607,12 @@ iss::status riscv_hart_msu_vp<BASE>::read(const address_type type, const access_
|
||||
if (unlikely(is_fetch(access) && (addr&(alignment-1)))) {
|
||||
fault_data = addr;
|
||||
if (access && iss::access_type::DEBUG) throw trap_access(0, addr);
|
||||
this->trap_state = (1 << 31); // issue trap 0
|
||||
this->reg.trap_state = (1 << 31); // issue trap 0
|
||||
return iss::Err;
|
||||
}
|
||||
try {
|
||||
if(!is_debug(access) && (addr&(alignment-1))){
|
||||
this->trap_state = 1<<31 | 4<<16;
|
||||
this->reg.trap_state = 1<<31 | 4<<16;
|
||||
fault_data=addr;
|
||||
return iss::Err;
|
||||
}
|
||||
@ -631,12 +631,12 @@ iss::status riscv_hart_msu_vp<BASE>::read(const address_type type, const access_
|
||||
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);
|
||||
if (unlikely(res != iss::Ok)){
|
||||
this->trap_state = (1 << 31) | (5 << 16); // issue trap 5 (load access fault
|
||||
this->reg.trap_state = (1 << 31) | (5 << 16); // issue trap 5 (load access fault
|
||||
fault_data=addr;
|
||||
}
|
||||
return res;
|
||||
} catch (trap_access &ta) {
|
||||
this->trap_state = (1 << 31) | ta.id;
|
||||
this->reg.trap_state = (1 << 31) | ta.id;
|
||||
fault_data=ta.addr;
|
||||
return iss::Err;
|
||||
}
|
||||
@ -652,7 +652,7 @@ iss::status riscv_hart_msu_vp<BASE>::read(const address_type type, const access_
|
||||
case 3: { // SFENCE:VMA upper
|
||||
auto tvm = state.mstatus.TVM;
|
||||
if (this->reg.PRIV == PRIV_S & tvm != 0) {
|
||||
this->trap_state = (1 << 31) | (2 << 16);
|
||||
this->reg.trap_state = (1 << 31) | (2 << 16);
|
||||
this->fault_data = this->reg.PC;
|
||||
return iss::Err;
|
||||
}
|
||||
@ -673,7 +673,7 @@ iss::status riscv_hart_msu_vp<BASE>::read(const address_type type, const access_
|
||||
}
|
||||
return iss::Ok;
|
||||
} catch (trap_access &ta) {
|
||||
this->trap_state = (1 << 31) | ta.id;
|
||||
this->reg.trap_state = (1 << 31) | ta.id;
|
||||
fault_data=ta.addr;
|
||||
return iss::Err;
|
||||
}
|
||||
@ -711,7 +711,7 @@ iss::status riscv_hart_msu_vp<BASE>::write(const address_type type, const access
|
||||
if (unlikely((access && iss::access_type::FETCH) && (addr & 0x1) == 1)) {
|
||||
fault_data = addr;
|
||||
if (access && iss::access_type::DEBUG) throw trap_access(0, addr);
|
||||
this->trap_state = (1 << 31); // issue trap 0
|
||||
this->reg.trap_state = (1 << 31); // issue trap 0
|
||||
return iss::Err;
|
||||
}
|
||||
try {
|
||||
@ -730,12 +730,12 @@ iss::status riscv_hart_msu_vp<BASE>::write(const address_type type, const access
|
||||
write_mem(phys_addr_t{access, space, addr}, length, data):
|
||||
write_mem(BASE::v2p(iss::addr_t{access, type, space, addr}), length, data);
|
||||
if (unlikely(res != iss::Ok)) {
|
||||
this->trap_state = (1 << 31) | (7 << 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;
|
||||
} catch (trap_access &ta) {
|
||||
this->trap_state = (1 << 31) | ta.id;
|
||||
this->reg.trap_state = (1 << 31) | ta.id;
|
||||
fault_data=ta.addr;
|
||||
return iss::Err;
|
||||
}
|
||||
@ -784,7 +784,7 @@ iss::status riscv_hart_msu_vp<BASE>::write(const address_type type, const access
|
||||
ptw.clear();
|
||||
auto tvm = state.mstatus.TVM;
|
||||
if (this->reg.PRIV == PRIV_S & tvm != 0) {
|
||||
this->trap_state = (1 << 31) | (2 << 16);
|
||||
this->reg.trap_state = (1 << 31) | (2 << 16);
|
||||
this->fault_data = this->reg.PC;
|
||||
return iss::Err;
|
||||
}
|
||||
@ -800,7 +800,7 @@ iss::status riscv_hart_msu_vp<BASE>::write(const address_type type, const access
|
||||
}
|
||||
return iss::Ok;
|
||||
} catch (trap_access &ta) {
|
||||
this->trap_state = (1 << 31) | ta.id;
|
||||
this->reg.trap_state = (1 << 31) | ta.id;
|
||||
fault_data=ta.addr;
|
||||
return iss::Err;
|
||||
}
|
||||
@ -846,7 +846,7 @@ template <typename BASE> iss::status riscv_hart_msu_vp<BASE>::write_reg(unsigned
|
||||
}
|
||||
|
||||
template <typename BASE> iss::status riscv_hart_msu_vp<BASE>::read_cycle(unsigned addr, reg_t &val) {
|
||||
auto cycle_val = this->icount + cycle_offset;
|
||||
auto cycle_val = this->reg.icount + cycle_offset;
|
||||
if (addr == mcycle) {
|
||||
val = static_cast<reg_t>(cycle_val);
|
||||
} else if (addr == mcycleh) {
|
||||
@ -868,7 +868,7 @@ template <typename BASE> iss::status riscv_hart_msu_vp<BASE>::write_cycle(unsign
|
||||
mcycle_csr = (static_cast<uint64_t>(val)<<32) + (mcycle_csr & 0xffffffff);
|
||||
}
|
||||
}
|
||||
cycle_offset = mcycle_csr-this->icount; // TODO: relying on wrap-around
|
||||
cycle_offset = mcycle_csr-this->reg.icount; // TODO: relying on wrap-around
|
||||
return iss::Ok;
|
||||
}
|
||||
|
||||
@ -899,7 +899,7 @@ template <typename BASE> iss::status riscv_hart_msu_vp<BASE>::write_instret(unsi
|
||||
}
|
||||
|
||||
template <typename BASE> iss::status riscv_hart_msu_vp<BASE>::read_time(unsigned addr, reg_t &val) {
|
||||
uint64_t time_val = this->icount / (100000000 / 32768 - 1); //-> ~3052;
|
||||
uint64_t time_val = this->reg.icount / (100000000 / 32768 - 1); //-> ~3052;
|
||||
if (addr == time) {
|
||||
val = static_cast<reg_t>(time_val);
|
||||
} else if (addr == timeh) {
|
||||
@ -968,7 +968,7 @@ template <typename BASE> iss::status riscv_hart_msu_vp<BASE>::write_epc(unsigned
|
||||
template <typename BASE> iss::status riscv_hart_msu_vp<BASE>::read_satp(unsigned addr, reg_t &val) {
|
||||
reg_t tvm = state.mstatus.TVM;
|
||||
if (this->reg.PRIV == PRIV_S & tvm != 0) {
|
||||
this->trap_state = (1 << 31) | (2 << 16);
|
||||
this->reg.trap_state = (1 << 31) | (2 << 16);
|
||||
this->fault_data = this->reg.PC;
|
||||
return iss::Err;
|
||||
}
|
||||
@ -979,7 +979,7 @@ template <typename BASE> iss::status riscv_hart_msu_vp<BASE>::read_satp(unsigned
|
||||
template <typename BASE> iss::status riscv_hart_msu_vp<BASE>::write_satp(unsigned addr, reg_t val) {
|
||||
reg_t tvm = state.mstatus.TVM;
|
||||
if (this->reg.PRIV == PRIV_S & tvm != 0) {
|
||||
this->trap_state = (1 << 31) | (2 << 16);
|
||||
this->reg.trap_state = (1 << 31) | (2 << 16);
|
||||
this->fault_data = this->reg.PC;
|
||||
return iss::Err;
|
||||
}
|
||||
@ -1024,18 +1024,6 @@ template <typename BASE> iss::status riscv_hart_msu_vp<BASE>::write_fcsr(unsigne
|
||||
template <typename BASE>
|
||||
iss::status riscv_hart_msu_vp<BASE>::read_mem(phys_addr_t paddr, unsigned length, uint8_t *const data) {
|
||||
switch (paddr.val) {
|
||||
case 0x0200BFF8: { // CLINT base, mtime reg
|
||||
if (sizeof(reg_t) < length) return iss::Err;
|
||||
reg_t time_val;
|
||||
this->read_csr(time, time_val);
|
||||
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);
|
||||
uint64_t offs = paddr.val & mem.page_addr_mask;
|
||||
std::copy(p.data() + offs, p.data() + offs + length, data);
|
||||
if (this->icount > 30000) data[3] |= 0x80;
|
||||
} break;
|
||||
default: {
|
||||
for(auto offs=0U; offs<length; ++offs) {
|
||||
*(data + offs)=mem[(paddr.val+offs)%mem.size()];
|
||||
@ -1048,30 +1036,13 @@ iss::status riscv_hart_msu_vp<BASE>::read_mem(phys_addr_t paddr, unsigned length
|
||||
template <typename BASE>
|
||||
iss::status riscv_hart_msu_vp<BASE>::write_mem(phys_addr_t paddr, unsigned length, const uint8_t *const data) {
|
||||
switch (paddr.val) {
|
||||
case 0x10013000: // UART0 base, TXFIFO reg
|
||||
case 0x10023000: // UART1 base, TXFIFO reg
|
||||
uart_buf << (char)data[0];
|
||||
case 0xFFFF0000: // UART0 base, TXFIFO reg
|
||||
if (((char)data[0]) == '\n' || data[0] == 0) {
|
||||
// LOG(INFO)<<"UART"<<((paddr.val>>16)&0x3)<<" send
|
||||
// '"<<uart_buf.str()<<"'";
|
||||
std::cout << uart_buf.str();
|
||||
LOG(INFO)<<"UART"<<((paddr.val>>12)&0x3)<<" send '"<<uart_buf.str()<<"'";
|
||||
uart_buf.str("");
|
||||
}
|
||||
} else if(((char)data[0]) != '\r')
|
||||
uart_buf << (char)data[0];
|
||||
break;
|
||||
case 0x10008000: { // HFROSC base, hfrosccfg reg
|
||||
mem_type::page_type &p = mem(paddr.val / mem.page_size);
|
||||
size_t offs = paddr.val & mem.page_addr_mask;
|
||||
std::copy(data, data + length, p.data() + offs);
|
||||
uint8_t &x = *(p.data() + offs + 3);
|
||||
if (x & 0x40) x |= 0x80; // hfroscrdy = 1 if hfroscen==1
|
||||
} break;
|
||||
case 0x10008008: { // HFROSC base, pllcfg reg
|
||||
mem_type::page_type &p = mem(paddr.val / mem.page_size);
|
||||
size_t offs = paddr.val & mem.page_addr_mask;
|
||||
std::copy(data, data + length, p.data() + offs);
|
||||
uint8_t &x = *(p.data() + offs + 3);
|
||||
x |= 0x80; // set pll lock upon writing
|
||||
} break;
|
||||
default: {
|
||||
mem_type::page_type &p = mem(paddr.val / mem.page_size);
|
||||
std::copy(data, data + length, p.data() + (paddr.val & mem.page_addr_mask));
|
||||
@ -1093,7 +1064,7 @@ iss::status riscv_hart_msu_vp<BASE>::write_mem(phys_addr_t paddr, unsigned lengt
|
||||
LOG(INFO) << "tohost value is 0x" << std::hex << hostvar << std::dec << " (" << hostvar
|
||||
<< "), stopping simulation";
|
||||
}
|
||||
this->trap_state=std::numeric_limits<uint32_t>::max();
|
||||
this->reg.trap_state=std::numeric_limits<uint32_t>::max();
|
||||
this->interrupt_sim=hostvar;
|
||||
break;
|
||||
//throw(iss::simulation_stopped(hostvar));
|
||||
@ -1162,7 +1133,7 @@ template <typename BASE> void riscv_hart_msu_vp<BASE>::check_interrupt() {
|
||||
if (enabled_interrupts != 0) {
|
||||
int res = 0;
|
||||
while ((enabled_interrupts & 1) == 0) enabled_interrupts >>= 1, res++;
|
||||
this->pending_trap = res << 16 | 1; // 0x80 << 24 | (cause << 16) | trap_id
|
||||
this->reg.pending_trap = res << 16 | 1; // 0x80 << 24 | (cause << 16) | trap_id
|
||||
}
|
||||
}
|
||||
|
||||
@ -1306,7 +1277,7 @@ template <typename BASE> uint64_t riscv_hart_msu_vp<BASE>::enter_trap(uint64_t f
|
||||
if (cur_priv != PRIV_M && ((csr[mideleg] >> cause) & 0x1) != 0)
|
||||
new_priv = (csr[sideleg] >> cause) & 0x1 ? PRIV_U : PRIV_S;
|
||||
csr[uepc | (new_priv << 8)] = this->reg.NEXT_PC; // store next address if interrupt
|
||||
this->pending_trap = 0;
|
||||
this->reg.pending_trap = 0;
|
||||
}
|
||||
size_t adr = ucause | (new_priv << 8);
|
||||
csr[adr] = (trap_id << 31) + cause;
|
||||
@ -1351,7 +1322,7 @@ template <typename BASE> uint64_t riscv_hart_msu_vp<BASE>::enter_trap(uint64_t f
|
||||
<< lvl[cur_priv] << " to " << lvl[new_priv];
|
||||
// reset trap state
|
||||
this->reg.PRIV = new_priv;
|
||||
this->trap_state = 0;
|
||||
this->reg.trap_state = 0;
|
||||
update_vm_info();
|
||||
return this->reg.NEXT_PC;
|
||||
}
|
||||
@ -1363,7 +1334,7 @@ template <typename BASE> uint64_t riscv_hart_msu_vp<BASE>::leave_trap(uint64_t f
|
||||
|
||||
auto tsr = state.mstatus.TSR;
|
||||
if (cur_priv == PRIV_S && inst_priv == PRIV_S && tsr != 0) {
|
||||
this->trap_state = (1 << 31) | (2 << 16);
|
||||
this->reg.trap_state = (1 << 31) | (2 << 16);
|
||||
this->fault_data = this->reg.PC;
|
||||
return this->reg.PC;
|
||||
}
|
||||
@ -1402,7 +1373,7 @@ template <typename BASE> void riscv_hart_msu_vp<BASE>::wait_until(uint64_t flags
|
||||
auto status = state.mstatus;
|
||||
auto tw = status.TW;
|
||||
if (this->reg.PRIV == PRIV_S && tw != 0) {
|
||||
this->trap_state = (1 << 31) | (2 << 16);
|
||||
this->reg.trap_state = (1 << 31) | (2 << 16);
|
||||
this->fault_data = this->reg.PC;
|
||||
}
|
||||
}
|
||||
|
@ -304,7 +304,7 @@ public:
|
||||
|
||||
void disass_output(uint64_t pc, const std::string instr) override {
|
||||
CLOG(INFO, disass) << fmt::format("0x{:016x} {:40} [p:{};s:0x{:x};c:{}]",
|
||||
pc, instr, lvl[this->reg.PRIV], (reg_t)state.mstatus, this->icount + cycle_offset);
|
||||
pc, instr, lvl[this->reg.PRIV], (reg_t)state.mstatus, this->reg.icount + cycle_offset);
|
||||
};
|
||||
|
||||
iss::instrumentation_if *get_instrumentation_if() override { return &instr_if; }
|
||||
@ -816,7 +816,7 @@ iss::status riscv_hart_mu_p<BASE, FEAT>::read(const address_type type, const acc
|
||||
if(!pmp_check(access, addr, length) && !is_debug(access)) {
|
||||
fault_data = addr;
|
||||
if (is_debug(access)) throw trap_access(0, addr);
|
||||
this->trap_state = (1UL << 31) | ((access==access_type::FETCH?1:5) << 16); // issue trap 1
|
||||
this->reg.trap_state = (1UL << 31) | ((access==access_type::FETCH?1:5) << 16); // issue trap 1
|
||||
return iss::Err;
|
||||
}
|
||||
}
|
||||
@ -824,12 +824,12 @@ iss::status riscv_hart_mu_p<BASE, FEAT>::read(const address_type type, const acc
|
||||
if (unlikely(is_fetch(access) && (addr&(alignment-1)))) {
|
||||
fault_data = addr;
|
||||
if (is_debug(access)) throw trap_access(0, addr);
|
||||
this->trap_state = (1UL << 31); // issue trap 0
|
||||
this->reg.trap_state = (1UL << 31); // issue trap 0
|
||||
return iss::Err;
|
||||
}
|
||||
try {
|
||||
if(!is_debug(access) && (addr&(alignment-1))){
|
||||
this->trap_state = (1UL << 31) | 4<<16;
|
||||
this->reg.trap_state = (1UL << 31) | 4<<16;
|
||||
fault_data=addr;
|
||||
return iss::Err;
|
||||
}
|
||||
@ -848,12 +848,12 @@ iss::status riscv_hart_mu_p<BASE, FEAT>::read(const address_type type, const acc
|
||||
res = hart_mem_rd_delegate( phys_addr, length, data);
|
||||
}
|
||||
if (unlikely(res != iss::Ok)){
|
||||
this->trap_state = (1UL << 31) | (5 << 16); // issue trap 5 (load access fault
|
||||
this->reg.trap_state = (1UL << 31) | (5 << 16); // issue trap 5 (load access fault
|
||||
fault_data=addr;
|
||||
}
|
||||
return res;
|
||||
} catch (trap_access &ta) {
|
||||
this->trap_state = (1UL << 31) | ta.id;
|
||||
this->reg.trap_state = (1UL << 31) | ta.id;
|
||||
fault_data=ta.addr;
|
||||
return iss::Err;
|
||||
}
|
||||
@ -879,7 +879,7 @@ iss::status riscv_hart_mu_p<BASE, FEAT>::read(const address_type type, const acc
|
||||
}
|
||||
return iss::Ok;
|
||||
} catch (trap_access &ta) {
|
||||
this->trap_state = (1UL << 31) | ta.id;
|
||||
this->reg.trap_state = (1UL << 31) | ta.id;
|
||||
fault_data=ta.addr;
|
||||
return iss::Err;
|
||||
}
|
||||
@ -918,19 +918,19 @@ iss::status riscv_hart_mu_p<BASE, FEAT>::write(const address_type type, const ac
|
||||
if(!pmp_check(access, addr, length) && (access&access_type::DEBUG) != access_type::DEBUG) {
|
||||
fault_data = addr;
|
||||
if (access && iss::access_type::DEBUG) throw trap_access(0, addr);
|
||||
this->trap_state = (1UL << 31) | (7 << 16); // issue trap 1
|
||||
this->reg.trap_state = (1UL << 31) | (7 << 16); // issue trap 1
|
||||
return iss::Err;
|
||||
}
|
||||
}
|
||||
if (unlikely(is_fetch(access) && (addr & 0x1) == 1)) {
|
||||
fault_data = addr;
|
||||
if (access && iss::access_type::DEBUG) throw trap_access(0, addr);
|
||||
this->trap_state = (1UL << 31); // issue trap 0
|
||||
this->reg.trap_state = (1UL << 31); // issue trap 0
|
||||
return iss::Err;
|
||||
}
|
||||
try {
|
||||
if(length>1 && (addr&(length-1)) && (access&access_type::DEBUG) != access_type::DEBUG){
|
||||
this->trap_state = (1UL << 31) | 6<<16;
|
||||
this->reg.trap_state = (1UL << 31) | 6<<16;
|
||||
fault_data=addr;
|
||||
return iss::Err;
|
||||
}
|
||||
@ -949,12 +949,12 @@ iss::status riscv_hart_mu_p<BASE, FEAT>::write(const address_type type, const ac
|
||||
res = hart_mem_wr_delegate( phys_addr, length, data);
|
||||
}
|
||||
if (unlikely(res != iss::Ok)) {
|
||||
this->trap_state = (1UL << 31) | (7 << 16); // issue trap 7 (Store/AMO access fault)
|
||||
this->reg.trap_state = (1UL << 31) | (7 << 16); // issue trap 7 (Store/AMO access fault)
|
||||
fault_data=addr;
|
||||
}
|
||||
return res;
|
||||
} catch (trap_access &ta) {
|
||||
this->trap_state = (1UL << 31) | ta.id;
|
||||
this->reg.trap_state = (1UL << 31) | ta.id;
|
||||
fault_data=ta.addr;
|
||||
return iss::Err;
|
||||
}
|
||||
@ -1014,7 +1014,7 @@ iss::status riscv_hart_mu_p<BASE, FEAT>::write(const address_type type, const ac
|
||||
}
|
||||
return iss::Ok;
|
||||
} catch (trap_access &ta) {
|
||||
this->trap_state = (1UL << 31) | ta.id;
|
||||
this->reg.trap_state = (1UL << 31) | ta.id;
|
||||
fault_data=ta.addr;
|
||||
return iss::Err;
|
||||
}
|
||||
@ -1060,7 +1060,7 @@ template <typename BASE, features_e FEAT> iss::status riscv_hart_mu_p<BASE, FEAT
|
||||
}
|
||||
|
||||
template <typename BASE, features_e FEAT> iss::status riscv_hart_mu_p<BASE, FEAT>::read_cycle(unsigned addr, reg_t &val) {
|
||||
auto cycle_val = this->icount + cycle_offset;
|
||||
auto cycle_val = this->reg.icount + cycle_offset;
|
||||
if (addr == mcycle) {
|
||||
val = static_cast<reg_t>(cycle_val);
|
||||
} else if (addr == mcycleh) {
|
||||
@ -1079,35 +1079,35 @@ template <typename BASE, features_e FEAT> iss::status riscv_hart_mu_p<BASE, FEAT
|
||||
mcycle_csr = (static_cast<uint64_t>(val)<<32) + (mcycle_csr & 0xffffffff);
|
||||
}
|
||||
}
|
||||
cycle_offset = mcycle_csr-this->icount; // TODO: relying on wrap-around
|
||||
cycle_offset = mcycle_csr-this->reg.icount; // TODO: relying on wrap-around
|
||||
return iss::Ok;
|
||||
}
|
||||
|
||||
template <typename BASE, features_e FEAT> iss::status riscv_hart_mu_p<BASE, FEAT>::read_instret(unsigned addr, reg_t &val) {
|
||||
if ((addr&0xff) == (minstret&0xff)) {
|
||||
val = static_cast<reg_t>(this->instret);
|
||||
val = static_cast<reg_t>(this->reg.instret);
|
||||
} else if ((addr&0xff) == (minstreth&0xff)) {
|
||||
val = static_cast<reg_t>(this->instret >> 32);
|
||||
val = static_cast<reg_t>(this->reg.instret >> 32);
|
||||
}
|
||||
return iss::Ok;
|
||||
}
|
||||
|
||||
template <typename BASE, features_e FEAT> iss::status riscv_hart_mu_p<BASE, FEAT>::write_instret(unsigned addr, reg_t val) {
|
||||
if (sizeof(typename traits<BASE>::reg_t) != 4) {
|
||||
this->instret = static_cast<uint64_t>(val);
|
||||
this->reg.instret = static_cast<uint64_t>(val);
|
||||
} else {
|
||||
if ((addr&0xff) == (minstret&0xff)) {
|
||||
this->instret = (this->instret & 0xffffffff00000000) + val;
|
||||
this->reg.instret = (this->reg.instret & 0xffffffff00000000) + val;
|
||||
} else {
|
||||
this->instret = (static_cast<uint64_t>(val)<<32) + (this->instret & 0xffffffff);
|
||||
this->reg.instret = (static_cast<uint64_t>(val)<<32) + (this->reg.instret & 0xffffffff);
|
||||
}
|
||||
}
|
||||
this->instret--;
|
||||
this->reg.instret--;
|
||||
return iss::Ok;
|
||||
}
|
||||
|
||||
template <typename BASE, features_e FEAT> iss::status riscv_hart_mu_p<BASE, FEAT>::read_time(unsigned addr, reg_t &val) {
|
||||
uint64_t time_val = this->icount / (100000000 / 32768 - 1); //-> ~3052;
|
||||
uint64_t time_val = this->reg.icount / (100000000 / 32768 - 1); //-> ~3052;
|
||||
if (addr == time) {
|
||||
val = static_cast<reg_t>(time_val);
|
||||
} else if (addr == timeh) {
|
||||
@ -1283,18 +1283,6 @@ iss::status riscv_hart_mu_p<BASE, FEAT>::write_xtvt(unsigned addr, reg_t val) {
|
||||
template <typename BASE, features_e FEAT>
|
||||
iss::status riscv_hart_mu_p<BASE, FEAT>::read_mem(phys_addr_t paddr, unsigned length, uint8_t *const data) {
|
||||
switch (paddr.val) {
|
||||
case 0x0200BFF8: { // CLINT base, mtime reg
|
||||
if (sizeof(reg_t) < length) return iss::Err;
|
||||
reg_t time_val;
|
||||
this->read_csr(time, time_val);
|
||||
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);
|
||||
uint64_t offs = paddr.val & mem.page_addr_mask;
|
||||
std::copy(p.data() + offs, p.data() + offs + length, data);
|
||||
if (this->icount > 30000) data[3] |= 0x80;
|
||||
} break;
|
||||
default: {
|
||||
for(auto offs=0U; offs<length; ++offs) {
|
||||
*(data + offs)=mem[(paddr.val+offs)%mem.size()];
|
||||
@ -1307,29 +1295,13 @@ iss::status riscv_hart_mu_p<BASE, FEAT>::read_mem(phys_addr_t paddr, unsigned le
|
||||
template <typename BASE, features_e FEAT>
|
||||
iss::status riscv_hart_mu_p<BASE, FEAT>::write_mem(phys_addr_t paddr, unsigned length, const uint8_t *const data) {
|
||||
switch (paddr.val) {
|
||||
case 0x10013000: // UART0 base, TXFIFO reg
|
||||
case 0x10023000: // UART1 base, TXFIFO reg
|
||||
uart_buf << (char)data[0];
|
||||
case 0xFFFF0000: // UART0 base, TXFIFO reg
|
||||
if (((char)data[0]) == '\n' || data[0] == 0) {
|
||||
LOG(INFO)<<"UART"<<((paddr.val>>16)&0x3)<<" send '"<<uart_buf.str()<<"'";
|
||||
std::cout << uart_buf.str();
|
||||
LOG(INFO)<<"UART"<<((paddr.val>>12)&0x3)<<" send '"<<uart_buf.str()<<"'";
|
||||
uart_buf.str("");
|
||||
}
|
||||
} else if(((char)data[0]) != '\r')
|
||||
uart_buf << (char)data[0];
|
||||
break;
|
||||
case 0x10008000: { // HFROSC base, hfrosccfg reg
|
||||
mem_type::page_type &p = mem(paddr.val / mem.page_size);
|
||||
size_t offs = paddr.val & mem.page_addr_mask;
|
||||
std::copy(data, data + length, p.data() + offs);
|
||||
uint8_t &x = *(p.data() + offs + 3);
|
||||
if (x & 0x40) x |= 0x80; // hfroscrdy = 1 if hfroscen==1
|
||||
} break;
|
||||
case 0x10008008: { // HFROSC base, pllcfg reg
|
||||
mem_type::page_type &p = mem(paddr.val / mem.page_size);
|
||||
size_t offs = paddr.val & mem.page_addr_mask;
|
||||
std::copy(data, data + length, p.data() + offs);
|
||||
uint8_t &x = *(p.data() + offs + 3);
|
||||
x |= 0x80; // set pll lock upon writing
|
||||
} break;
|
||||
default: {
|
||||
mem_type::page_type &p = mem(paddr.val / mem.page_size);
|
||||
std::copy(data, data + length, p.data() + (paddr.val & mem.page_addr_mask));
|
||||
@ -1351,7 +1323,7 @@ iss::status riscv_hart_mu_p<BASE, FEAT>::write_mem(phys_addr_t paddr, unsigned l
|
||||
LOG(INFO) << "tohost value is 0x" << std::hex << hostvar << std::dec << " (" << hostvar
|
||||
<< "), stopping simulation";
|
||||
}
|
||||
this->trap_state=std::numeric_limits<uint32_t>::max();
|
||||
this->reg.trap_state=std::numeric_limits<uint32_t>::max();
|
||||
this->interrupt_sim=hostvar;
|
||||
break;
|
||||
//throw(iss::simulation_stopped(hostvar));
|
||||
@ -1436,14 +1408,14 @@ template <typename BASE, features_e FEAT> void riscv_hart_mu_p<BASE, FEAT>::chec
|
||||
enabled_interrupts >>= 1;
|
||||
res++;
|
||||
}
|
||||
this->pending_trap = res << 16 | 1; // 0x80 << 24 | (cause << 16) | trap_id
|
||||
this->reg.pending_trap = res << 16 | 1; // 0x80 << 24 | (cause << 16) | trap_id
|
||||
}
|
||||
}
|
||||
|
||||
template <typename BASE, features_e FEAT> uint64_t riscv_hart_mu_p<BASE, FEAT>::enter_trap(uint64_t flags, uint64_t addr, uint64_t instr) {
|
||||
// flags are ACTIVE[31:31], CAUSE[30:16], TRAPID[15:0]
|
||||
// calculate and write mcause val
|
||||
if(flags==std::numeric_limits<uint64_t>::max()) flags=this->trap_state;
|
||||
if(flags==std::numeric_limits<uint64_t>::max()) flags=this->reg.trap_state;
|
||||
auto trap_id = bit_sub<0, 16>(flags);
|
||||
auto cause = bit_sub<16, 15>(flags);
|
||||
if (trap_id == 0 && cause == 11) cause = 0x8 + this->reg.PRIV; // adjust environment call cause
|
||||
@ -1490,7 +1462,7 @@ template <typename BASE, features_e FEAT> uint64_t riscv_hart_mu_p<BASE, FEAT>::
|
||||
if (this->reg.PRIV != PRIV_M && ((csr[mideleg] >> cause) & 0x1) != 0)
|
||||
new_priv = PRIV_U;
|
||||
csr[uepc | (new_priv << 8)] = this->reg.NEXT_PC; // store next address if interrupt
|
||||
this->pending_trap = 0;
|
||||
this->reg.pending_trap = 0;
|
||||
}
|
||||
size_t adr = ucause | (new_priv << 8);
|
||||
csr[adr] = (trap_id << (traits<BASE>::XLEN-1)) + cause;
|
||||
@ -1543,7 +1515,7 @@ template <typename BASE, features_e FEAT> uint64_t riscv_hart_mu_p<BASE, FEAT>::
|
||||
<< lvl[this->reg.PRIV] << " to " << lvl[new_priv];
|
||||
// reset trap state
|
||||
this->reg.PRIV = new_priv;
|
||||
this->trap_state = 0;
|
||||
this->reg.trap_state = 0;
|
||||
return this->reg.NEXT_PC;
|
||||
}
|
||||
|
||||
@ -1552,7 +1524,7 @@ template <typename BASE, features_e FEAT> uint64_t riscv_hart_mu_p<BASE, FEAT>::
|
||||
auto inst_priv = (flags & 0x3)? 3:0;
|
||||
if(inst_priv>cur_priv){
|
||||
auto trap_val = 0x80ULL << 24 | (2 << 16); // illegal instruction
|
||||
this->trap_state = trap_val;
|
||||
this->reg.trap_state = trap_val;
|
||||
this->reg.NEXT_PC = std::numeric_limits<uint32_t>::max();
|
||||
} else {
|
||||
auto status = state.mstatus;
|
||||
|
@ -55,8 +55,8 @@ void tgc_c::reset(uint64_t address) {
|
||||
reg.PC=address;
|
||||
reg.NEXT_PC=reg.PC;
|
||||
reg.PRIV=0x3;
|
||||
trap_state=0;
|
||||
icount=0;
|
||||
reg.trap_state=0;
|
||||
reg.icount=0;
|
||||
}
|
||||
|
||||
uint8_t *tgc_c::get_regs_base_ptr() {
|
||||
|
@ -189,7 +189,7 @@ struct tgc_c: public arch_if {
|
||||
|
||||
uint8_t* get_regs_base_ptr() override;
|
||||
|
||||
inline uint64_t get_icount() { return icount; }
|
||||
inline uint64_t get_icount() { return reg.icount; }
|
||||
|
||||
inline bool should_stop() { return interrupt_sim; }
|
||||
|
||||
@ -207,7 +207,7 @@ struct tgc_c: public arch_if {
|
||||
|
||||
virtual iss::sync_type needed_sync() const { return iss::NO_SYNC; }
|
||||
|
||||
inline uint32_t get_last_branch() { return last_branch; }
|
||||
inline uint32_t get_last_branch() { return reg.last_branch; }
|
||||
|
||||
|
||||
#pragma pack(push, 1)
|
||||
@ -256,12 +256,6 @@ struct tgc_c: public arch_if {
|
||||
uint32_t last_branch = 0;
|
||||
} reg;
|
||||
#pragma pack(pop)
|
||||
uint32_t trap_state = 0, pending_trap = 0;
|
||||
uint64_t icount = 0;
|
||||
uint64_t cycle = 0;
|
||||
uint64_t instret = 0;
|
||||
uint32_t instruction = 0;
|
||||
uint32_t last_branch = 0;
|
||||
std::array<address_type, 4> addr_mode;
|
||||
|
||||
uint64_t interrupt_sim=0;
|
||||
|
@ -71,7 +71,7 @@ int main(int argc, char *argv[]) {
|
||||
("elf,f", po::value<std::vector<std::string>>(), "ELF file(s) to load")
|
||||
("mem,m", po::value<std::string>(), "the memory input file")
|
||||
("plugin,p", po::value<std::vector<std::string>>(), "plugin to activate")
|
||||
("backend", po::value<std::string>()->default_value("interp"), "the memory input file")
|
||||
("backend", po::value<std::string>()->default_value("interp"), "the ISS backend to use, options are: interp, tcc")
|
||||
("isa", po::value<std::string>()->default_value("tgc_c"), "isa to use for simulation");
|
||||
// clang-format on
|
||||
auto parsed = po::command_line_parser(argc, argv).options(desc).allow_unregistered().run();
|
||||
|
@ -115,7 +115,7 @@ protected:
|
||||
|
||||
inline void raise(uint16_t trap_id, uint16_t cause){
|
||||
auto trap_val = 0x80ULL << 24 | (cause << 16) | trap_id;
|
||||
this->core.trap_state = trap_val;
|
||||
this->core.reg.trap_state = trap_val;
|
||||
this->template get_reg<uint32_t>(traits::NEXT_PC) = std::numeric_limits<uint32_t>::max();
|
||||
}
|
||||
|
||||
@ -322,16 +322,16 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
|
||||
auto pc=start;
|
||||
auto* PC = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::PC]);
|
||||
auto* NEXT_PC = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::NEXT_PC]);
|
||||
auto& trap_state = this->core.trap_state;
|
||||
auto& icount = this->core.icount;
|
||||
auto& cycle = this->core.cycle;
|
||||
auto& instret = this->core.instret;
|
||||
auto& instr = this->core.instruction;
|
||||
auto& trap_state = this->core.reg.trap_state;
|
||||
auto& icount = this->core.reg.icount;
|
||||
auto& cycle = this->core.reg.cycle;
|
||||
auto& instret = this->core.reg.instret;
|
||||
auto& instr = this->core.reg.instruction;
|
||||
// we fetch at max 4 byte, alignment is 2
|
||||
auto *const data = reinterpret_cast<uint8_t*>(&instr);
|
||||
|
||||
while(!this->core.should_stop() &&
|
||||
!(is_count_limit_enabled(cond) && this->core.get_icount() >= icount_limit)){
|
||||
!(is_count_limit_enabled(cond) && icount >= icount_limit)){
|
||||
if(fetch_ins(pc, data)!=iss::Ok){
|
||||
this->do_sync(POST_SYNC, std::numeric_limits<unsigned>::max());
|
||||
pc.val = super::core.enter_trap(std::numeric_limits<uint64_t>::max(), pc.val, 0);
|
||||
@ -340,7 +340,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
|
||||
(instr == 0x0000006f || (instr&0xffff)==0xa001)) throw simulation_stopped(0); // 'J 0' or 'C.J 0'
|
||||
auto inst_id = decode_inst_id(instr);
|
||||
// pre execution stuff
|
||||
this->core.last_branch = 0;
|
||||
this->core.reg.last_branch = 0;
|
||||
if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, static_cast<unsigned>(inst_id));
|
||||
switch(inst_id){
|
||||
case arch::traits<ARCH>::opcode_e::LUI: {
|
||||
@ -422,7 +422,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
|
||||
*(X+rd) = *PC + 4;
|
||||
}
|
||||
*NEXT_PC = *PC + (int32_t)sext<21>(imm);
|
||||
this->core.last_branch = 1;
|
||||
this->core.reg.last_branch = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -457,7 +457,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
|
||||
*(X+rd) = *PC + 4;
|
||||
}
|
||||
*NEXT_PC = new_pc & ~ 0x1;
|
||||
this->core.last_branch = 1;
|
||||
this->core.reg.last_branch = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -489,7 +489,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
|
||||
}
|
||||
else {
|
||||
*NEXT_PC = *PC + (int16_t)sext<13>(imm);
|
||||
this->core.last_branch = 1;
|
||||
this->core.reg.last_branch = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -522,7 +522,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
|
||||
}
|
||||
else {
|
||||
*NEXT_PC = *PC + (int16_t)sext<13>(imm);
|
||||
this->core.last_branch = 1;
|
||||
this->core.reg.last_branch = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -555,7 +555,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
|
||||
}
|
||||
else {
|
||||
*NEXT_PC = *PC + (int16_t)sext<13>(imm);
|
||||
this->core.last_branch = 1;
|
||||
this->core.reg.last_branch = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -588,7 +588,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
|
||||
}
|
||||
else {
|
||||
*NEXT_PC = *PC + (int16_t)sext<13>(imm);
|
||||
this->core.last_branch = 1;
|
||||
this->core.reg.last_branch = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -621,7 +621,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
|
||||
}
|
||||
else {
|
||||
*NEXT_PC = *PC + (int16_t)sext<13>(imm);
|
||||
this->core.last_branch = 1;
|
||||
this->core.reg.last_branch = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -654,7 +654,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
|
||||
}
|
||||
else {
|
||||
*NEXT_PC = *PC + (int16_t)sext<13>(imm);
|
||||
this->core.last_branch = 1;
|
||||
this->core.reg.last_branch = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -683,7 +683,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
|
||||
else {
|
||||
uint32_t load_address = *(X+rs1) + (int16_t)sext<12>(imm);
|
||||
int8_t read_res = super::template read_mem<int8_t>(traits::MEM, load_address);
|
||||
if(this->core.trap_state>=0x80000000UL) goto TRAP_LB;
|
||||
if(this->core.reg.trap_state>=0x80000000UL) goto TRAP_LB;
|
||||
int8_t res = (int8_t)read_res;
|
||||
if(rd != 0) {
|
||||
*(X+rd) = (uint32_t)res;
|
||||
@ -714,7 +714,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
|
||||
else {
|
||||
uint32_t load_address = *(X+rs1) + (int16_t)sext<12>(imm);
|
||||
int16_t read_res = super::template read_mem<int16_t>(traits::MEM, load_address);
|
||||
if(this->core.trap_state>=0x80000000UL) goto TRAP_LH;
|
||||
if(this->core.reg.trap_state>=0x80000000UL) goto TRAP_LH;
|
||||
int16_t res = (int16_t)read_res;
|
||||
if(rd != 0) {
|
||||
*(X+rd) = (uint32_t)res;
|
||||
@ -745,7 +745,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
|
||||
else {
|
||||
uint32_t load_address = *(X+rs1) + (int16_t)sext<12>(imm);
|
||||
int32_t read_res = super::template read_mem<int32_t>(traits::MEM, load_address);
|
||||
if(this->core.trap_state>=0x80000000UL) goto TRAP_LW;
|
||||
if(this->core.reg.trap_state>=0x80000000UL) goto TRAP_LW;
|
||||
int32_t res = (int32_t)read_res;
|
||||
if(rd != 0) {
|
||||
*(X+rd) = (uint32_t)res;
|
||||
@ -776,7 +776,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
|
||||
else {
|
||||
uint32_t load_address = *(X+rs1) + (int16_t)sext<12>(imm);
|
||||
uint8_t read_res = super::template read_mem<uint8_t>(traits::MEM, load_address);
|
||||
if(this->core.trap_state>=0x80000000UL) goto TRAP_LBU;
|
||||
if(this->core.reg.trap_state>=0x80000000UL) goto TRAP_LBU;
|
||||
uint8_t res = (uint8_t)read_res;
|
||||
if(rd != 0) {
|
||||
*(X+rd) = (uint32_t)res;
|
||||
@ -807,7 +807,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
|
||||
else {
|
||||
uint32_t load_address = *(X+rs1) + (int16_t)sext<12>(imm);
|
||||
uint16_t read_res = super::template read_mem<uint16_t>(traits::MEM, load_address);
|
||||
if(this->core.trap_state>=0x80000000UL) goto TRAP_LHU;
|
||||
if(this->core.reg.trap_state>=0x80000000UL) goto TRAP_LHU;
|
||||
uint16_t res = (uint16_t)read_res;
|
||||
if(rd != 0) {
|
||||
*(X+rd) = (uint32_t)res;
|
||||
@ -838,7 +838,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
|
||||
else {
|
||||
uint32_t store_address = *(X+rs1) + (int16_t)sext<12>(imm);
|
||||
super::template write_mem<uint8_t>(traits::MEM, store_address, (int8_t)*(X+rs2));
|
||||
if(this->core.trap_state>=0x80000000UL) goto TRAP_SB;
|
||||
if(this->core.reg.trap_state>=0x80000000UL) goto TRAP_SB;
|
||||
}
|
||||
}
|
||||
TRAP_SB:break;
|
||||
@ -865,7 +865,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
|
||||
else {
|
||||
uint32_t store_address = *(X+rs1) + (int16_t)sext<12>(imm);
|
||||
super::template write_mem<uint16_t>(traits::MEM, store_address, (int16_t)*(X+rs2));
|
||||
if(this->core.trap_state>=0x80000000UL) goto TRAP_SH;
|
||||
if(this->core.reg.trap_state>=0x80000000UL) goto TRAP_SH;
|
||||
}
|
||||
}
|
||||
TRAP_SH:break;
|
||||
@ -892,7 +892,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
|
||||
else {
|
||||
uint32_t store_address = *(X+rs1) + (int16_t)sext<12>(imm);
|
||||
super::template write_mem<uint32_t>(traits::MEM, store_address, (int32_t)*(X+rs2));
|
||||
if(this->core.trap_state>=0x80000000UL) goto TRAP_SW;
|
||||
if(this->core.reg.trap_state>=0x80000000UL) goto TRAP_SW;
|
||||
}
|
||||
}
|
||||
TRAP_SW:break;
|
||||
@ -1428,7 +1428,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
|
||||
// execute instruction
|
||||
{
|
||||
super::template write_mem<uint8_t>(traits::FENCE, traits::fence, pred << 4 | succ);
|
||||
if(this->core.trap_state>=0x80000000UL) goto TRAP_FENCE;
|
||||
if(this->core.reg.trap_state>=0x80000000UL) goto TRAP_FENCE;
|
||||
}
|
||||
TRAP_FENCE:break;
|
||||
}// @suppress("No break at end of case")
|
||||
@ -1507,15 +1507,15 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
|
||||
uint32_t xrs1 = *(X+rs1);
|
||||
if(rd != 0) {
|
||||
uint32_t read_res = super::template read_mem<uint32_t>(traits::CSR, csr);
|
||||
if(this->core.trap_state>=0x80000000UL) goto TRAP_CSRRW;
|
||||
if(this->core.reg.trap_state>=0x80000000UL) goto TRAP_CSRRW;
|
||||
uint32_t xrd = read_res;
|
||||
super::template write_mem<uint32_t>(traits::CSR, csr, xrs1);
|
||||
if(this->core.trap_state>=0x80000000UL) goto TRAP_CSRRW;
|
||||
if(this->core.reg.trap_state>=0x80000000UL) goto TRAP_CSRRW;
|
||||
*(X+rd) = xrd;
|
||||
}
|
||||
else {
|
||||
super::template write_mem<uint32_t>(traits::CSR, csr, xrs1);
|
||||
if(this->core.trap_state>=0x80000000UL) goto TRAP_CSRRW;
|
||||
if(this->core.reg.trap_state>=0x80000000UL) goto TRAP_CSRRW;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1542,12 +1542,12 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
|
||||
}
|
||||
else {
|
||||
uint32_t read_res = super::template read_mem<uint32_t>(traits::CSR, csr);
|
||||
if(this->core.trap_state>=0x80000000UL) goto TRAP_CSRRS;
|
||||
if(this->core.reg.trap_state>=0x80000000UL) goto TRAP_CSRRS;
|
||||
uint32_t xrd = read_res;
|
||||
uint32_t xrs1 = *(X+rs1);
|
||||
if(rs1 != 0) {
|
||||
super::template write_mem<uint32_t>(traits::CSR, csr, xrd | xrs1);
|
||||
if(this->core.trap_state>=0x80000000UL) goto TRAP_CSRRS;
|
||||
if(this->core.reg.trap_state>=0x80000000UL) goto TRAP_CSRRS;
|
||||
}
|
||||
if(rd != 0) {
|
||||
*(X+rd) = xrd;
|
||||
@ -1577,12 +1577,12 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
|
||||
}
|
||||
else {
|
||||
uint32_t read_res = super::template read_mem<uint32_t>(traits::CSR, csr);
|
||||
if(this->core.trap_state>=0x80000000UL) goto TRAP_CSRRC;
|
||||
if(this->core.reg.trap_state>=0x80000000UL) goto TRAP_CSRRC;
|
||||
uint32_t xrd = read_res;
|
||||
uint32_t xrs1 = *(X+rs1);
|
||||
if(rs1 != 0) {
|
||||
super::template write_mem<uint32_t>(traits::CSR, csr, xrd & ~ xrs1);
|
||||
if(this->core.trap_state>=0x80000000UL) goto TRAP_CSRRC;
|
||||
if(this->core.reg.trap_state>=0x80000000UL) goto TRAP_CSRRC;
|
||||
}
|
||||
if(rd != 0) {
|
||||
*(X+rd) = xrd;
|
||||
@ -1612,10 +1612,10 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
|
||||
}
|
||||
else {
|
||||
uint32_t read_res = super::template read_mem<uint32_t>(traits::CSR, csr);
|
||||
if(this->core.trap_state>=0x80000000UL) goto TRAP_CSRRWI;
|
||||
if(this->core.reg.trap_state>=0x80000000UL) goto TRAP_CSRRWI;
|
||||
uint32_t xrd = read_res;
|
||||
super::template write_mem<uint32_t>(traits::CSR, csr, (uint32_t)zimm);
|
||||
if(this->core.trap_state>=0x80000000UL) goto TRAP_CSRRWI;
|
||||
if(this->core.reg.trap_state>=0x80000000UL) goto TRAP_CSRRWI;
|
||||
if(rd != 0) {
|
||||
*(X+rd) = xrd;
|
||||
}
|
||||
@ -1644,11 +1644,11 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
|
||||
}
|
||||
else {
|
||||
uint32_t read_res = super::template read_mem<uint32_t>(traits::CSR, csr);
|
||||
if(this->core.trap_state>=0x80000000UL) goto TRAP_CSRRSI;
|
||||
if(this->core.reg.trap_state>=0x80000000UL) goto TRAP_CSRRSI;
|
||||
uint32_t xrd = read_res;
|
||||
if(zimm != 0) {
|
||||
super::template write_mem<uint32_t>(traits::CSR, csr, xrd | (uint32_t)zimm);
|
||||
if(this->core.trap_state>=0x80000000UL) goto TRAP_CSRRSI;
|
||||
if(this->core.reg.trap_state>=0x80000000UL) goto TRAP_CSRRSI;
|
||||
}
|
||||
if(rd != 0) {
|
||||
*(X+rd) = xrd;
|
||||
@ -1678,11 +1678,11 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
|
||||
}
|
||||
else {
|
||||
uint32_t read_res = super::template read_mem<uint32_t>(traits::CSR, csr);
|
||||
if(this->core.trap_state>=0x80000000UL) goto TRAP_CSRRCI;
|
||||
if(this->core.reg.trap_state>=0x80000000UL) goto TRAP_CSRRCI;
|
||||
uint32_t xrd = read_res;
|
||||
if(zimm != 0) {
|
||||
super::template write_mem<uint32_t>(traits::CSR, csr, xrd & ~ ((uint32_t)zimm));
|
||||
if(this->core.trap_state>=0x80000000UL) goto TRAP_CSRRCI;
|
||||
if(this->core.reg.trap_state>=0x80000000UL) goto TRAP_CSRRCI;
|
||||
}
|
||||
if(rd != 0) {
|
||||
*(X+rd) = xrd;
|
||||
@ -1707,7 +1707,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
|
||||
// execute instruction
|
||||
{
|
||||
super::template write_mem<uint16_t>(traits::FENCE, traits::fencei, imm);
|
||||
if(this->core.trap_state>=0x80000000UL) goto TRAP_FENCE_I;
|
||||
if(this->core.reg.trap_state>=0x80000000UL) goto TRAP_FENCE_I;
|
||||
}
|
||||
TRAP_FENCE_I:break;
|
||||
}// @suppress("No break at end of case")
|
||||
@ -2015,7 +2015,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
|
||||
{
|
||||
uint32_t load_address = *(X+rs1 + 8) + uimm;
|
||||
int32_t read_res = super::template read_mem<int32_t>(traits::MEM, load_address);
|
||||
if(this->core.trap_state>=0x80000000UL) goto TRAP_CLW;
|
||||
if(this->core.reg.trap_state>=0x80000000UL) goto TRAP_CLW;
|
||||
*(X+rd + 8) = (int32_t)read_res;
|
||||
}
|
||||
TRAP_CLW:break;
|
||||
@ -2038,7 +2038,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
|
||||
{
|
||||
uint32_t load_address = *(X+rs1 + 8) + uimm;
|
||||
super::template write_mem<uint32_t>(traits::MEM, load_address, (int32_t)*(X+rs2 + 8));
|
||||
if(this->core.trap_state>=0x80000000UL) goto TRAP_CSW;
|
||||
if(this->core.reg.trap_state>=0x80000000UL) goto TRAP_CSW;
|
||||
}
|
||||
TRAP_CSW:break;
|
||||
}// @suppress("No break at end of case")
|
||||
@ -2097,7 +2097,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
|
||||
{
|
||||
*(X+1) = *PC + 2;
|
||||
*NEXT_PC = *PC + (int16_t)sext<12>(imm);
|
||||
this->core.last_branch = 1;
|
||||
this->core.reg.last_branch = 1;
|
||||
}
|
||||
TRAP_CJAL:break;
|
||||
}// @suppress("No break at end of case")
|
||||
@ -2342,7 +2342,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
|
||||
// execute instruction
|
||||
{
|
||||
*NEXT_PC = *PC + (int16_t)sext<12>(imm);
|
||||
this->core.last_branch = 1;
|
||||
this->core.reg.last_branch = 1;
|
||||
}
|
||||
TRAP_CJ:break;
|
||||
}// @suppress("No break at end of case")
|
||||
@ -2363,7 +2363,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
|
||||
{
|
||||
if(*(X+rs1 + 8) == 0) {
|
||||
*NEXT_PC = *PC + (int16_t)sext<9>(imm);
|
||||
this->core.last_branch = 1;
|
||||
this->core.reg.last_branch = 1;
|
||||
}
|
||||
}
|
||||
TRAP_CBEQZ:break;
|
||||
@ -2385,7 +2385,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
|
||||
{
|
||||
if(*(X+rs1 + 8) != 0) {
|
||||
*NEXT_PC = *PC + (int16_t)sext<9>(imm);
|
||||
this->core.last_branch = 1;
|
||||
this->core.reg.last_branch = 1;
|
||||
}
|
||||
}
|
||||
TRAP_CBNEZ:break;
|
||||
@ -2436,7 +2436,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
|
||||
}
|
||||
else {
|
||||
int32_t read_res = super::template read_mem<int32_t>(traits::MEM, *(X+2) + uimm);
|
||||
if(this->core.trap_state>=0x80000000UL) goto TRAP_CLWSP;
|
||||
if(this->core.reg.trap_state>=0x80000000UL) goto TRAP_CLWSP;
|
||||
int32_t res = read_res;
|
||||
*(X+rd) = (int32_t)res;
|
||||
}
|
||||
@ -2485,7 +2485,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
|
||||
{
|
||||
if(rs1 && rs1 < traits::RFS) {
|
||||
*NEXT_PC = *(X+rs1 % traits::RFS) & ~ 0x1;
|
||||
this->core.last_branch = 1;
|
||||
this->core.reg.last_branch = 1;
|
||||
}
|
||||
else {
|
||||
raise(0, 2);
|
||||
@ -2553,7 +2553,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
|
||||
uint32_t new_pc = *(X+rs1);
|
||||
*(X+1) = *PC + 2;
|
||||
*NEXT_PC = new_pc & ~ 0x1;
|
||||
this->core.last_branch = 1;
|
||||
this->core.reg.last_branch = 1;
|
||||
}
|
||||
}
|
||||
TRAP_CJALR:break;
|
||||
@ -2592,7 +2592,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
|
||||
else {
|
||||
uint32_t offs = *(X+2) + uimm;
|
||||
super::template write_mem<uint32_t>(traits::MEM, offs, (uint32_t)*(X+rs2));
|
||||
if(this->core.trap_state>=0x80000000UL) goto TRAP_CSWSP;
|
||||
if(this->core.reg.trap_state>=0x80000000UL) goto TRAP_CSWSP;
|
||||
}
|
||||
}
|
||||
TRAP_CSWSP:break;
|
||||
@ -2618,8 +2618,8 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
|
||||
// post execution stuff
|
||||
process_spawn_blocks();
|
||||
if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, static_cast<unsigned>(inst_id));
|
||||
// if(!this->core.trap_state) // update trap state if there is a pending interrupt
|
||||
// this->core.trap_state = this->core.pending_trap;
|
||||
// if(!this->core.reg.trap_state) // update trap state if there is a pending interrupt
|
||||
// this->core.reg.trap_state = this->core.reg.pending_trap;
|
||||
// trap check
|
||||
if(trap_state!=0){
|
||||
super::core.enter_trap(trap_state, pc.val, instr);
|
||||
@ -2630,7 +2630,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
|
||||
cycle++;
|
||||
pc.val=*NEXT_PC;
|
||||
this->core.reg.PC = this->core.reg.NEXT_PC;
|
||||
this->core.trap_state = this->core.pending_trap;
|
||||
this->core.reg.trap_state = this->core.reg.pending_trap;
|
||||
}
|
||||
}
|
||||
return pc;
|
||||
|
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user