@@ -291,7 +291,7 @@ class mmu_t
291291 return have_reservation;
292292 }
293293
294- static const reg_t ICACHE_ENTRIES = 1024 ;
294+ static const reg_t ICACHE_ENTRIES = 8 ;
295295
296296 inline size_t icache_index (reg_t addr)
297297 {
@@ -310,22 +310,26 @@ class mmu_t
310310
311311 inline icache_entry_t * refill_icache (reg_t addr, icache_entry_t * entry)
312312 {
313- insn_bits_t insn = fetch_insn_parcel (addr);
313+ insn_bits_t insn;
314+ unsigned length;
314315
315- int length = insn_length (insn);
316+ if (auto [tlb_hit, host_addr, paddr] = access_tlb (tlb_insn, addr);
317+ tlb_hit && ((addr % PGSIZE) + sizeof (insn_bits_t ) <= PGSIZE)) {
318+ insn = from_le (*(insn_parcel_t *)host_addr);
319+ length = insn_length (insn);
316320
317- if (likely (length == 4 )) {
318- insn |= (insn_bits_t )fetch_insn_parcel (addr + 2 ) << 16 ;
319- } else if (length == 2 ) {
320- // entire instruction already fetched
321- } else if (length == 6 ) {
322- insn |= (insn_bits_t )fetch_insn_parcel (addr + 2 ) << 16 ;
323- insn |= (insn_bits_t )fetch_insn_parcel (addr + 4 ) << 32 ;
321+ for (unsigned pos = sizeof (insn_parcel_t ); unlikely (pos < length); pos += sizeof (insn_parcel_t )) {
322+ insn |= (insn_bits_t )from_le (*(insn_parcel_t *)(host_addr + pos)) << (8 * pos);
323+ length = insn_length (insn);
324+ }
324325 } else {
325- static_assert (sizeof (insn_bits_t ) == 8 , " insn_bits_t must be uint64_t" );
326- insn |= (insn_bits_t )fetch_insn_parcel (addr + 2 ) << 16 ;
327- insn |= (insn_bits_t )fetch_insn_parcel (addr + 4 ) << 32 ;
328- insn |= (insn_bits_t )fetch_insn_parcel (addr + 6 ) << 48 ;
326+ insn = fetch_insn_parcel (addr);
327+ length = insn_length (insn);
328+
329+ for (unsigned pos = sizeof (insn_parcel_t ); unlikely (pos < length); pos += sizeof (insn_parcel_t )) {
330+ insn |= fetch_insn_parcel (addr + pos) << (8 * pos);
331+ length = insn_length (insn);
332+ }
329333 }
330334
331335 insn_fetch_t fetch = {proc->decode_insn (insn), insn};
0 commit comments