#define FSR_NXA (FPEXC_NX << FSR_AEXC_SHIFT)
#define FSR_AEXC (FSR_NVA | FSR_OFA | FSR_UFA | FSR_DZA | FSR_NXA)
+#define insn_length(x) \
+ (((x) & 0x03) < 0x03 ? 2 : \
+ ((x) & 0x1f) < 0x1f ? 4 : \
+ ((x) & 0x3f) < 0x3f ? 6 : \
+ 8)
+
typedef uint64_t insn_bits_t;
class insn_t
{
insn_t() = default;
insn_t(insn_bits_t bits) : b(bits) {}
insn_bits_t bits() { return b; }
+ int length() { return insn_length(b); }
int64_t i_imm() { return int64_t(b) >> 20; }
int64_t s_imm() { return x(7, 5) + (xs(25, 7) << 5); }
int64_t sb_imm() { return (x(8, 4) << 1) + (x(25,6) << 5) + (x(7,1) << 11) + (imm_sign() << 12); }
#define sext_xprlen(x) (((sreg_t)(x) << (64-xprlen)) >> (64-xprlen))
#define zext_xprlen(x) (((reg_t)(x) << (64-xprlen)) >> (64-xprlen))
-#define insn_length(x) \
- (((x) & 0x03) < 0x03 ? 2 : \
- ((x) & 0x1f) < 0x1f ? 4 : \
- ((x) & 0x3f) < 0x3f ? 6 : \
- 8)
-
#define set_pc(x) (npc = sext_xprlen(x))
#define validate_csr(which, write) ({ \
throw trap_t((1ULL << ((state.sr & SR_S64) ? 63 : 31)) + i);
}
-static void commit_log(state_t* state, insn_t insn)
+static void commit_log(state_t* state, reg_t pc, insn_t insn)
{
#ifdef RISCV_ENABLE_COMMITLOG
if (state->sr & SR_EI) {
if (state->log_reg_write.addr) {
- fprintf(stderr, "0x%016" PRIx64 " (0x%08" PRIx64 ") %c%2u 0x%016" PRIx64 "\n",
- state->pc, insn.bits(),
+ uint64_t mask = (insn.length() == 8 ? uint64_t(0) : (uint64_t(1) << (insn.length() * 8))) - 1;
+ fprintf(stderr, "0x%016" PRIx64 " (0x%08" PRIx64 ") %c%2" PRIx64 " 0x%016" PRIx64 "\n",
+ pc, insn.bits() & mask,
state->log_reg_write.addr & 1 ? 'f' : 'x',
state->log_reg_write.addr >> 1, state->log_reg_write.data);
- }
- else {
- fprintf(stderr, "0x%016" PRIx64 " (0x%08" PRIx64 ")\n",
- state->pc, insn.bits());
+ } else {
+ fprintf(stderr, "0x%016" PRIx64 " (0x%08" PRIx64 ")\n", pc, insn.bits());
}
}
state->log_reg_write.addr = 0;
static reg_t execute_insn(processor_t* p, reg_t pc, insn_fetch_t fetch)
{
reg_t npc = fetch.func(p, fetch.insn, pc);
- commit_log(p->get_state(), fetch.insn);
+ commit_log(p->get_state(), pc, fetch.insn);
p->update_histogram(pc);
return npc;
}