aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Waterman <andrew@sifive.com>2020-07-04 05:17:48 -0700
committerGitHub <noreply@github.com>2020-07-04 05:17:48 -0700
commit4ae887c1ffd54f9e33461bbe6774693eb41267a0 (patch)
tree992b44b2e301f93e7a2c760ba8a338828b1d0c4b
parent61f0dab33f7e529cc709908840311a8a7dcb23ce (diff)
parent580ef6a6a519ea40d2680eed26d3c6e75bf4f763 (diff)
downloadspike-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.h8
-rw-r--r--riscv/execute.cc67
-rw-r--r--riscv/insns/vmvnfr_v.h9
-rw-r--r--riscv/processor.cc95
-rw-r--r--riscv/processor.h2
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));