f64cbaa268113a6d8f986a3ed24fb5d7fc70bd06
1 // See LICENSE for license details.
7 static void commit_log(state_t
* state
, reg_t pc
, insn_t insn
)
9 #ifdef RISCV_ENABLE_COMMITLOG
10 uint64_t mask
= (insn
.length() == 8 ? uint64_t(0) : (uint64_t(1) << (insn
.length() * 8))) - 1;
11 if (state
->log_reg_write
.addr
) {
12 fprintf(stderr
, "0x%016" PRIx64
" (0x%08" PRIx64
") %c%2" PRIu64
" 0x%016" PRIx64
"\n",
15 state
->log_reg_write
.addr
& 1 ? 'f' : 'x',
16 state
->log_reg_write
.addr
>> 1,
17 state
->log_reg_write
.data
);
19 fprintf(stderr
, "0x%016" PRIx64
" (0x%08" PRIx64
")\n", pc
, insn
.bits() & mask
);
21 state
->log_reg_write
.addr
= 0;
25 inline void processor_t::update_histogram(size_t pc
)
27 #ifdef RISCV_ENABLE_HISTOGRAM
33 static reg_t
execute_insn(processor_t
* p
, reg_t pc
, insn_fetch_t fetch
)
35 reg_t npc
= fetch
.func(p
, fetch
.insn
, pc
);
36 if (npc
!= PC_SERIALIZE
) {
37 commit_log(p
->get_state(), pc
, fetch
.insn
);
38 p
->update_histogram(pc
);
43 // fetch/decode/execute loop
44 void processor_t::step(size_t n
)
46 while (run
&& n
> 0) {
51 #define advance_pc() \
52 if (unlikely(pc == PC_SERIALIZE)) { \
54 state.serialized = true; \
70 insn_fetch_t fetch
= mmu
->load_insn(pc
);
71 if (!state
.serialized
)
73 pc
= execute_insn(this, pc
, fetch
);
77 else while (instret
< n
)
79 size_t idx
= _mmu
->icache_index(pc
);
80 auto ic_entry
= _mmu
->access_icache(pc
);
82 #define ICACHE_ACCESS(i) { \
83 insn_fetch_t fetch = ic_entry->data; \
85 pc = execute_insn(this, pc, fetch); \
86 if (i == mmu_t::ICACHE_ENTRIES-1) break; \
87 if (unlikely(ic_entry->tag != pc)) goto miss; \
88 if (unlikely(instret+1 == n)) break; \
102 // refill I$ if it looks like there wasn't a taken branch
103 if (pc
> (ic_entry
-1)->tag
&& pc
<= (ic_entry
-1)->tag
+ MAX_INSN_LENGTH
)
104 _mmu
->refill_icache(pc
, ic_entry
);
112 state
.minstret
+= instret
;