diff options
author | Andrew Waterman <andrew@sifive.com> | 2020-07-04 05:17:48 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-07-04 05:17:48 -0700 |
commit | 4ae887c1ffd54f9e33461bbe6774693eb41267a0 (patch) | |
tree | 992b44b2e301f93e7a2c760ba8a338828b1d0c4b | |
parent | 61f0dab33f7e529cc709908840311a8a7dcb23ce (diff) | |
parent | 580ef6a6a519ea40d2680eed26d3c6e75bf4f763 (diff) | |
download | spike-4ae887c1ffd54f9e33461bbe6774693eb41267a0.zip spike-4ae887c1ffd54f9e33461bbe6774693eb41267a0.tar.gz spike-4ae887c1ffd54f9e33461bbe6774693eb41267a0.tar.bz2 |
Merge pull request #499 from chihminchao/commitlog-2020-07-02
Commitlog 2020 07 02
-rw-r--r-- | riscv/decode.h | 8 | ||||
-rw-r--r-- | riscv/execute.cc | 67 | ||||
-rw-r--r-- | riscv/insns/vmvnfr_v.h | 9 | ||||
-rw-r--r-- | riscv/processor.cc | 95 | ||||
-rw-r--r-- | riscv/processor.h | 2 |
5 files changed, 142 insertions, 39 deletions
diff --git a/riscv/decode.h b/riscv/decode.h index 71caa58..34fa1d2 100644 --- a/riscv/decode.h +++ b/riscv/decode.h @@ -180,16 +180,18 @@ private: #else /* 0 : int * 1 : floating - * 2 : vector + * 2 : vector reg + * 3 : vector hint + * 4 : csr */ # define WRITE_REG(reg, value) ({ \ reg_t wdata = (value); /* value may have side effects */ \ - STATE.log_reg_write[(reg) << 2] = {wdata, 0}; \ + STATE.log_reg_write[(reg) << 4] = {wdata, 0}; \ STATE.XPR.write(reg, wdata); \ }) # define WRITE_FREG(reg, value) ({ \ freg_t wdata = freg(value); /* value may have side effects */ \ - STATE.log_reg_write[((reg) << 2) | 1] = wdata; \ + STATE.log_reg_write[((reg) << 4) | 1] = wdata; \ DO_WRITE_FREG(reg, wdata); \ }) # define WRITE_VSTATUS STATE.log_reg_write[3] = {0, 0}; diff --git a/riscv/execute.cc b/riscv/execute.cc index 7e89cd1..4ed2753 100644 --- a/riscv/execute.cc +++ b/riscv/execute.cc @@ -2,6 +2,7 @@ #include "processor.h" #include "mmu.h" +#include "disasm.h" #include <cassert> #ifdef RISCV_ENABLE_COMMITLOG @@ -23,40 +24,41 @@ static void commit_log_stash_privilege(processor_t* p) static void commit_log_print_value(FILE *log_file, int width, const void *data) { assert(log_file); - const uint64_t *arr = (const uint64_t *)data; - - fprintf(log_file, "0x"); - for (int idx = width / 64 - 1; idx >= 0; --idx) { - fprintf(log_file, "%016" PRIx64, arr[idx]); - } -} - -static void commit_log_print_value(FILE *log_file, - int width, uint64_t hi, uint64_t lo) -{ - assert(log_file); switch (width) { case 8: - fprintf(log_file, "0x%01" PRIx8, (uint8_t)lo); + fprintf(log_file, "0x%01" PRIx8, *(const uint8_t *)data); break; case 16: - fprintf(log_file, "0x%04" PRIx16, (uint16_t)lo); + fprintf(log_file, "0x%04" PRIx16, *(const uint16_t *)data); break; case 32: - fprintf(log_file, "0x%08" PRIx32, (uint32_t)lo); + fprintf(log_file, "0x%08" PRIx32, *(const uint32_t *)data); break; case 64: - fprintf(log_file, "0x%016" PRIx64, lo); - break; - case 128: - fprintf(log_file, "0x%016" PRIx64 "%016" PRIx64, hi, lo); + fprintf(log_file, "0x%016" PRIx64, *(const uint64_t *)data); break; default: - abort(); + // max lengh of vector + if (((width - 1) & width) == 0) { + const uint64_t *arr = (const uint64_t *)data; + + fprintf(log_file, "0x"); + for (int idx = width / 64 - 1; idx >= 0; --idx) { + fprintf(log_file, "%016" PRIx64, arr[idx]); + } + } else { + abort(); + } + break; } } +static void commit_log_print_value(FILE *log_file, int width, uint64_t val) +{ + commit_log_print_value(log_file, width, &val); +} + static void commit_log_print_insn(processor_t *p, reg_t pc, insn_t insn) { FILE *log_file = p->get_log_file(); @@ -69,9 +71,9 @@ static void commit_log_print_insn(processor_t *p, reg_t pc, insn_t insn) int flen = p->get_state()->last_inst_flen; fprintf(log_file, "%1d ", priv); - commit_log_print_value(log_file, xlen, 0, pc); + commit_log_print_value(log_file, xlen, pc); fprintf(log_file, " ("); - commit_log_print_value(log_file, insn.length() * 8, 0, insn.bits()); + commit_log_print_value(log_file, insn.length() * 8, insn.bits()); fprintf(log_file, ")"); bool show_vec = false; @@ -81,10 +83,10 @@ static void commit_log_print_insn(processor_t *p, reg_t pc, insn_t insn) char prefix; int size; - int rd = item.first >> 2; + int rd = item.first >> 4; bool is_vec = false; bool is_vreg = false; - switch (item.first & 3) { + switch (item.first & 0xf) { case 0: size = xlen; prefix = 'x'; @@ -101,6 +103,10 @@ static void commit_log_print_insn(processor_t *p, reg_t pc, insn_t insn) case 3: is_vec = true; break; + case 4: + size = xlen; + prefix = 'c'; + break; default: assert("can't been here" && 0); break; @@ -116,24 +122,27 @@ static void commit_log_print_insn(processor_t *p, reg_t pc, insn_t insn) } if (!is_vec) { - fprintf(log_file, " %c%2d ", prefix, rd); + if (prefix == 'c') + fprintf(log_file, " c%d_%s ", rd, csr_name(rd)); + else + fprintf(log_file, " %c%2d ", prefix, rd); if (is_vreg) commit_log_print_value(log_file, size, &p->VU.elt<uint8_t>(rd, 0)); else - commit_log_print_value(log_file, size, item.second.v[1], item.second.v[0]); + commit_log_print_value(log_file, size, item.second.v); } } for (auto item : load) { fprintf(log_file, " mem "); - commit_log_print_value(log_file, xlen, 0, std::get<0>(item)); + commit_log_print_value(log_file, xlen, std::get<0>(item)); } for (auto item : store) { fprintf(log_file, " mem "); - commit_log_print_value(log_file, xlen, 0, std::get<0>(item)); + commit_log_print_value(log_file, xlen, std::get<0>(item)); fprintf(log_file, " "); - commit_log_print_value(log_file, std::get<2>(item) << 3, 0, std::get<1>(item)); + commit_log_print_value(log_file, std::get<2>(item) << 3, std::get<1>(item)); } fprintf(log_file, "\n"); } diff --git a/riscv/insns/vmvnfr_v.h b/riscv/insns/vmvnfr_v.h index 51045ce..0813d69 100644 --- a/riscv/insns/vmvnfr_v.h +++ b/riscv/insns/vmvnfr_v.h @@ -6,10 +6,9 @@ const reg_t vs2 = insn.rs2(); const reg_t len = insn.rs1() + 1; require((vd & (len - 1)) == 0); require((vs2 & (len - 1)) == 0); -if (vd != vs2) { - for (reg_t i = 0; i < len; ++i) { - memcpy(&P.VU.elt<uint8_t>(vd + i, 0, true), - &P.VU.elt<uint8_t>(vs2 + i, 0), P.VU.vlenb); - } +const reg_t size = len * P.VU.vlenb; +if (vd != vs2 && P.VU.vstart < size) { + memcpy(&P.VU.elt<uint8_t>(vd, P.VU.vstart, true), + &P.VU.elt<uint8_t>(vs2, P.VU.vstart), size - P.VU.vstart); } P.VU.vstart = 0; diff --git a/riscv/processor.cc b/riscv/processor.cc index b779004..d6348a8 100644 --- a/riscv/processor.cc +++ b/riscv/processor.cc @@ -660,6 +660,13 @@ int processor_t::paddr_bits() void processor_t::set_csr(int which, reg_t val) { +#if defined(RISCV_ENABLE_COMMITLOG) +#define LOG_CSR(rd) \ + STATE.log_reg_write[((which) << 4) | 4] = {get_csr(rd), 0}; +#else +#define LOG_CSR(rd) +#endif + val = zext_xlen(val); reg_t supervisor_ints = supports_extension('S') ? MIP_SSIP | MIP_STIP | MIP_SEIP : 0; reg_t coprocessor_ints = (ext != NULL) << IRQ_COP; @@ -676,8 +683,10 @@ void processor_t::set_csr(int which, reg_t val) bool locked = state.pmpcfg[i] & PMP_L; bool next_locked = i+1 < state.max_pmp && (state.pmpcfg[i+1] & PMP_L); bool next_tor = i+1 < state.max_pmp && (state.pmpcfg[i+1] & PMP_A) == PMP_TOR; - if (i < n_pmp && !locked && !(next_locked && next_tor)) + if (i < n_pmp && !locked && !(next_locked && next_tor)) { state.pmpaddr[i] = val & ((reg_t(1) << (MAX_PADDR_BITS - PMP_SHIFT)) - 1); + LOG_CSR(which); + } mmu->flush_tlb(); } @@ -693,6 +702,7 @@ void processor_t::set_csr(int which, reg_t val) if (lg_pmp_granularity != PMP_SHIFT && (cfg & PMP_A) == PMP_NA4) cfg |= PMP_NAPOT; // Disallow A=NA4 when granularity > 4 state.pmpcfg[i] = cfg; + LOG_CSR(which); } } mmu->flush_tlb(); @@ -926,6 +936,89 @@ void processor_t::set_csr(int which, reg_t val) VU.vxrm = val & 0x3ul; break; } + +#if defined(RISCV_ENABLE_COMMITLOG) + switch (which) + { + case CSR_FFLAGS: + LOG_CSR(CSR_MSTATUS); + LOG_CSR(CSR_FFLAGS); + break; + case CSR_FRM: + LOG_CSR(CSR_MSTATUS); + LOG_CSR(CSR_FRM); + break; + case CSR_FCSR: + LOG_CSR(CSR_MSTATUS); + LOG_CSR(CSR_FFLAGS); + LOG_CSR(CSR_FRM); + break; + case CSR_VCSR: + LOG_CSR(CSR_MSTATUS); + LOG_CSR(CSR_VXSAT); + LOG_CSR(CSR_VXRM); + break; + + case CSR_VSTART: + LOG_CSR(CSR_MSTATUS); + LOG_CSR(CSR_VSTART); + break; + case CSR_VXSAT: + LOG_CSR(CSR_MSTATUS); + LOG_CSR(CSR_VXSAT); + break; + case CSR_VXRM: + LOG_CSR(CSR_MSTATUS); + LOG_CSR(CSR_VXRM); + break; + + case CSR_SSTATUS: + LOG_CSR(CSR_MSTATUS); + LOG_CSR(CSR_SSTATUS); + break; + case CSR_SIP: + LOG_CSR(CSR_MIP); + LOG_CSR(CSR_SIP); + break; + case CSR_SIE: + LOG_CSR(CSR_MIE); + LOG_CSR(CSR_SIE); + break; + + case CSR_MSTATUS: + case CSR_MIP: + case CSR_MIE: + case CSR_MIDELEG: + case CSR_MEDELEG: + case CSR_MINSTRET: + case CSR_MCYCLE: + case CSR_MINSTRETH: + case CSR_MCYCLEH: + case CSR_SCOUNTEREN: + case CSR_MCOUNTEREN: + case CSR_SATP: + case CSR_SEPC: + case CSR_STVEC: + case CSR_SSCRATCH: + case CSR_SCAUSE: + case CSR_STVAL: + case CSR_MEPC: + case CSR_MTVEC: + case CSR_MSCRATCH: + case CSR_MCAUSE: + case CSR_MTVAL: + case CSR_MISA: + case CSR_TSELECT: + case CSR_TDATA1: + case CSR_TDATA2: + case CSR_DCSR: + case CSR_DPC: + case CSR_DSCRATCH0: + case CSR_DSCRATCH1: + LOG_CSR(which); + break; + } +#endif } // Note that get_csr is sometimes called when read side-effects should not diff --git a/riscv/processor.h b/riscv/processor.h index 676a52d..68e13d8 100644 --- a/riscv/processor.h +++ b/riscv/processor.h @@ -481,7 +481,7 @@ public: #ifdef RISCV_ENABLE_COMMITLOG if (is_write) - p->get_state()->log_reg_write[((vReg) << 2) | 2] = {0, 0}; + p->get_state()->log_reg_write[((vReg) << 4) | 2] = {0, 0}; #endif T *regStart = (T*)((char*)reg_file + vReg * (VLEN >> 3)); |