From: Toni Wilen Date: Mon, 8 Jun 2020 17:54:03 +0000 (+0300) Subject: 68020/030 prefetch and MMU tweaks. X-Git-Tag: 4400~15 X-Git-Url: https://git.unchartedbackwaters.co.uk/w/?a=commitdiff_plain;h=71cb316dc2f387b37c278e3d38be98ef25e2f1d6;p=francis%2Fwinuae.git 68020/030 prefetch and MMU tweaks. --- diff --git a/cpummu30.cpp b/cpummu30.cpp index 96d14ae5..e4019a8e 100644 --- a/cpummu30.cpp +++ b/cpummu30.cpp @@ -38,6 +38,12 @@ #include "cpummu030.h" #include "cputbl.h" +// Prefetch mode and prefetch bus error: always flush and refill prefetch pipeline +#define MMU030_ALWAYS_FULL_PREFETCH 1 + // if CPU is 68030 and faulted access' addressing mode was -(an) or (an)+ +// register content is not restored when exception starts. +#define MMU030_REG_FIXUP 1 + #define MMU030_OP_DBG_MSG 0 #define MMU030_ATC_DBG_MSG 0 #define MMU030_REG_DBG_MSG 0 @@ -91,7 +97,7 @@ static struct mmufastcache030 atc_data_cache_write[MMUFASTCACHE_ENTRIES030]; #endif /* for debugging messages */ -char table_letter[4] = {'A','B','C','D'}; +static char table_letter[4] = {'A','B','C','D'}; static const uae_u32 mmu030_size[3] = { MMU030_SSW_SIZE_B, MMU030_SSW_SIZE_W, MMU030_SSW_SIZE_L }; @@ -514,7 +520,7 @@ static bool mmu_op30_pload (uaecptr pc, uae_u32 opcode, uae_u16 next, uaecptr ex if (!mmu_op30_helper_get_fc(next, &fc)) return true; -#if 0 +#if MMU030_OP_DBG_MSG write_log (_T("PLOAD%c: Create ATC entry for %08X, FC = %i\n"), write?'W':'R', extra, fc); #endif @@ -530,7 +536,7 @@ bool mmu_op30_pflush (uaecptr pc, uae_u32 opcode, uae_u16 next, uaecptr extra) uae_u32 fc_base; uae_u32 fc_bits = next & 0x7f; -#if 0 +#if MMU030_OP_DBG_MSG switch (mode) { case 0x1: write_log(_T("PFLUSH: Flush all entries\n")); @@ -623,8 +629,8 @@ TT_info mmu030_decode_tt(uae_u32 TT) { ret.fc_base = (TT&TT_FC_BASE)>>4; ret.addr_base = TT & TT_ADDR_BASE; ret.addr_mask = ~(((TT&TT_ADDR_MASK)<<8)|0x00FFFFFF); - -#if 0 + +#if MMU030_OP_DBG_MSG if ((TT&TT_ENABLE) && !(TT&TT_RWM)) { write_log(_T("MMU Warning: Transparent translation of read-modify-write cycle is not correctly handled!\n")); } @@ -1035,7 +1041,7 @@ static void mmu030_atc_handle_history_bit(int entry_num) { mmu030.atc[j].mru = 0; } mmu030.atc[entry_num].mru = 1; -#if MMU030_ATC_DBG_MSG +#if MMU030_ATC_DBG_MSG > 1 write_log(_T("ATC: No more history zero-bits. Reset all.\n")); #endif } @@ -1256,13 +1262,13 @@ static uae_u32 mmu030_table_search(uaecptr addr, uae_u32 fc, bool write, int lev if ((tc_030&TC_ENABLE_SUPERVISOR) && super) { descr[0] = (srp_030>>32)&0xFFFFFFFF; descr[1] = srp_030&0xFFFFFFFF; -#if MMU030_REG_DBG_MSG +#if MMU030_REG_DBG_MSG > 2 write_log(_T("Supervisor Root Pointer: %08X%08X\n"),descr[0],descr[1]); #endif // MMU030_REG_DBG_MSG } else { descr[0] = (crp_030>>32)&0xFFFFFFFF; descr[1] = crp_030&0xFFFFFFFF; -#if MMU030_REG_DBG_MSG +#if MMU030_REG_DBG_MSG > 2 write_log(_T("CPU Root Pointer: %08X%08X\n"),descr[0],descr[1]); #endif } @@ -1310,12 +1316,12 @@ static uae_u32 mmu030_table_search(uaecptr addr, uae_u32 fc, bool write, int lev if (next_size==4) { descr[0] = desc_get_long(descr_addr[descr_num]); -#if MMU030_REG_DBG_MSG +#if MMU030_REG_DBG_MSG > 2 write_log(_T("Next descriptor: %08X\n"),descr[0]); #endif } else { desc_get_quad(descr_addr[descr_num], descr); -#if MMU030_REG_DBG_MSG +#if MMU030_REG_DBG_MSG > 2 write_log(_T("Next descriptor: %08X%08X\n"),descr[0],descr[1]); #endif } @@ -1331,7 +1337,7 @@ static uae_u32 mmu030_table_search(uaecptr addr, uae_u32 fc, bool write, int lev mmu030.status |= MMUSR_INVALID; goto stop_search; case DESCR_TYPE_EARLY_TERM: -#if MMU030_REG_DBG_MSG +#if MMU030_REG_DBG_MSG > 2 write_log(_T("Early termination page descriptor!\n")); #endif early_termination = true; @@ -1376,7 +1382,7 @@ static uae_u32 mmu030_table_search(uaecptr addr, uae_u32 fc, bool write, int lev addr_position = (descr_size==4) ? 0 : 1; table_addr = descr[addr_position]&DESCR_TD_ADDR_MASK; table_index = (addr&mmu030.translation.table[t].mask)>>mmu030.translation.table[t].shift; -#if MMU030_REG_DBG_MSG +#if MMU030_REG_DBG_MSG > 2 write_log(_T("Table %c at %08X: index = %i, "),table_letter[t],table_addr,table_index); #endif // MMU030_REG_DBG_MSG t++; /* Proceed to the next table */ @@ -1406,12 +1412,12 @@ static uae_u32 mmu030_table_search(uaecptr addr, uae_u32 fc, bool write, int lev if (next_size==4) { descr[0] = desc_get_long(descr_addr[descr_num]); -#if MMU030_REG_DBG_MSG +#if MMU030_REG_DBG_MSG > 2 write_log(_T("Next descriptor: %08X\n"),descr[0]); #endif } else { desc_get_quad(descr_addr[descr_num], descr); -#if MMU030_REG_DBG_MSG +#if MMU030_REG_DBG_MSG > 2 write_log(_T("Next descriptor: %08X%08X\n"),descr[0],descr[1]); #endif } @@ -1431,7 +1437,7 @@ static uae_u32 mmu030_table_search(uaecptr addr, uae_u32 fc, bool write, int lev case DESCR_TYPE_EARLY_TERM: /* go to last level table handling code */ if (t<=mmu030.translation.last_table) { -#if MMU030_REG_DBG_MSG +#if MMU030_REG_DBG_MSG > 2 write_log(_T("Early termination page descriptor!\n")); #endif early_termination = true; @@ -1456,7 +1462,7 @@ static uae_u32 mmu030_table_search(uaecptr addr, uae_u32 fc, bool write, int lev addr_position = (descr_size==4) ? 0 : 1; indirect_addr = descr[addr_position]&DESCR_ID_ADDR_MASK; -#if MMU030_REG_DBG_MSG +#if MMU030_REG_DBG_MSG > 2 write_log(_T("Page indirect descriptor at %08X: "),indirect_addr); #endif @@ -1466,12 +1472,12 @@ static uae_u32 mmu030_table_search(uaecptr addr, uae_u32 fc, bool write, int lev if (next_size==4) { descr[0] = desc_get_long(descr_addr[descr_num]); -#if MMU030_REG_DBG_MSG +#if MMU030_REG_DBG_MSG > 2 write_log(_T("descr = %08X\n"),descr[0]); #endif } else { desc_get_quad(descr_addr[descr_num], descr); -#if MMU030_REG_DBG_MSG +#if MMU030_REG_DBG_MSG > 2 write_log(_T("descr = %08X%08X"),descr[0],descr[1]); #endif } @@ -1557,7 +1563,7 @@ static uae_u32 mmu030_table_search(uaecptr addr, uae_u32 fc, bool write, int lev t++; } while (t<=mmu030.translation.last_table); page_addr = addr&unused_fields_mask; -#if MMU030_REG_DBG_MSG +#if MMU030_REG_DBG_MSG > 1 write_log(_T("Logical address unused bits: %08X (mask = %08X)\n"), page_addr,unused_fields_mask); #endif @@ -1566,7 +1572,7 @@ static uae_u32 mmu030_table_search(uaecptr addr, uae_u32 fc, bool write, int lev /* Get page address */ addr_position = (descr_size==4) ? 0 : 1; page_addr += (descr[addr_position]&DESCR_PD_ADDR_MASK); -#if MMU030_REG_DBG_MSG +#if MMU030_REG_DBG_MSG > 2 write_log(_T("Page at %08X\n"),page_addr); #endif // MMU030_REG_DBG_MSG @@ -1610,7 +1616,7 @@ static uae_u32 mmu030_table_search(uaecptr addr, uae_u32 fc, bool write, int lev break; } } -#if MMU030_REG_DBG_MSG +#if MMU030_REG_DBG_MSG > 2 write_log(_T("ATC is full. Replacing entry %i\n"), i); #endif } @@ -1637,7 +1643,7 @@ static uae_u32 mmu030_table_search(uaecptr addr, uae_u32 fc, bool write, int lev mmu030_flush_cache(mmu030.atc[i].logical.addr); -#if MMU030_ATC_DBG_MSG +#if MMU030_ATC_DBG_MSG > 1 write_log(_T("ATC create entry(%i): logical = %08X, physical = %08X, FC = %i\n"), i, mmu030.atc[i].logical.addr, mmu030.atc[i].physical.addr, mmu030.atc[i].logical.fc); @@ -1758,16 +1764,15 @@ static void dump_opcode(uae_u16 opcode) break; } } - write_log(_T("%04x %s.%c"), opcode, lookup->name, size); + write_log(_T(" %04x %s.%c"), opcode, lookup->name, size); } #endif -// if CPU is 68030 and faulted access' addressing mode was -(an) or (an)+ -// register content is not restored when exception starts. static uae_u8 mmu030fixupreg(int i) { - struct mmufixup *m = &mmufixup[i]; uae_u8 v = 0; +#if MMU030_REG_FIXUP + struct mmufixup *m = &mmufixup[i]; if (m->reg < 0) return v; if (!(m->reg & 0x300)) @@ -1777,11 +1782,13 @@ static uae_u8 mmu030fixupreg(int i) if (m->reg & 0x200) // -(an)? v |= 1 << 5; v |= 1 << 6; +#endif return v; } static void mmu030fixupmod(uae_u8 data, int dir, int idx) { +#if MMU030_REG_FIXUP if (!data) return; int reg = data & 7; @@ -1794,6 +1801,8 @@ static void mmu030fixupmod(uae_u8 data, int dir, int idx) struct mmufixup *m = &mmufixup[idx]; m->value += adj; } + write_log("fixup %04x %d %d\n", mmu030_opcode & 0xffff, reg, adj); +#endif } void mmu030_page_fault(uaecptr addr, bool read, int flags, uae_u32 fc) @@ -1805,7 +1814,6 @@ void mmu030_page_fault(uaecptr addr, bool read, int flags, uae_u32 fc) } regs.wb3_status = 0; regs.wb2_status = 0; - regs.mmu_fault_addr = addr; if (fc & 1) { regs.mmu_ssw = MMU030_SSW_DF | (MMU030_SSW_DF << 1); if (!(mmu030_state[1] & MMU030_STATEFLAG1_LASTWRITE)) { @@ -1815,20 +1823,14 @@ void mmu030_page_fault(uaecptr addr, bool read, int flags, uae_u32 fc) mmu030fixupmod(regs.wb3_status, 0, 1); } } else { + // only used by data fault but word sounds nice + flags = MMU030_SSW_SIZE_W; if (currprefs.cpu_compatible) { regs.wb2_status = mmu030fixupreg(0); mmu030fixupmod(regs.wb2_status, 0, 0); regs.wb3_status = mmu030fixupreg(1); mmu030fixupmod(regs.wb3_status, 0, 1); - if (regs.prefetch020_valid[1] != 1 && regs.prefetch020_valid[2] == 1) { - regs.mmu_ssw = MMU030_SSW_FC | MMU030_SSW_RC; - } else if (regs.prefetch020_valid[2] != 1) { - regs.mmu_ssw = MMU030_SSW_FB | MMU030_SSW_RB; - } else { - // This happens when CPU prefetches from page - // end - 4 and both pages are originally invalid. - regs.mmu_ssw = MMU030_SSW_FC | MMU030_SSW_RC; - } + regs.mmu_ssw = MMU030_SSW_FB | MMU030_SSW_RB; } else { regs.mmu_ssw = MMU030_SSW_FB | MMU030_SSW_RB; } @@ -1837,6 +1839,7 @@ void mmu030_page_fault(uaecptr addr, bool read, int flags, uae_u32 fc) regs.mmu_ssw |= flags; regs.mmu_ssw |= fc; regs.mmu_ssw |= islrmw030 ? MMU030_SSW_RM : 0; + regs.mmu_fault_addr = addr; // temporary store in 68040+ variables because stack frame creation may modify them. regs.wb3_data = mmu030_data_buffer_out; regs.wb2_address = mmu030_state[1]; @@ -1844,21 +1847,19 @@ void mmu030_page_fault(uaecptr addr, bool read, int flags, uae_u32 fc) mm030_stageb_address = addr; #if MMUDEBUG - write_log(_T("MMU: %02x la=%08X SSW=%04x read=%d size=%d fc=%d pc=%08x ob=%08x "), + write_log(_T("MMU: %02x la=%08X SSW=%04x read=%d size=%d fc=%d pc=%08x ob=%08x"), (mmu030_state[1] & MMU030_STATEFLAG1_LASTWRITE) ? 0xa : 0xb, addr, regs.mmu_ssw, read, (flags & MMU030_SSW_SIZE_B) ? 1 : (flags & MMU030_SSW_SIZE_W) ? 2 : 4, fc, - regs.instruction_pc, mmu030_data_buffer_out, mmu030_opcode & 0xffff); + regs.instruction_pc, mmu030_data_buffer_out); dump_opcode(mmu030_opcode & 0xffff); + if (regs.opcode != mmu030_opcode) + dump_opcode(regs.opcode & 0xffff); write_log(_T("\n")); #endif ismoves030 = false; islrmw030 = false; -#if 0 - if (addr == 0xc1026ea0) - write_log("!"); -#endif #if 0 if (mmu030_state[1] & MMU030_STATEFLAG1_SUBACCESS0) write_log("!"); @@ -1927,7 +1928,7 @@ static uaecptr mmu030_put_atc(uaecptr addr, int l, uae_u32 fc, uae_u32 size) { uae_u32 addr_mask = mmu030.translation.page.imask; uae_u32 physical_addr = mmu030.atc[l].physical.addr&addr_mask; -#if MMU030_ATC_DBG_MSG +#if MMU030_ATC_DBG_MSG > 1 write_log(_T("ATC match(%i): page addr = %08X, index = %08X\n"), l, physical_addr, page_index); #endif @@ -1949,7 +1950,7 @@ static uaecptr mmu030_get_atc(uaecptr addr, int l, uae_u32 fc, uae_u32 size) { uae_u32 addr_mask = mmu030.translation.page.imask; uae_u32 physical_addr = mmu030.atc[l].physical.addr&addr_mask; -#if MMU030_ATC_DBG_MSG +#if MMU030_ATC_DBG_MSG > 1 write_log(_T("ATC match(%i): page addr = %08X, index = %08X\n"), l, physical_addr, page_index); #endif @@ -1971,7 +1972,7 @@ static uaecptr mmu030_get_i_atc(uaecptr addr, int l, uae_u32 fc, uae_u32 size) { uae_u32 addr_mask = mmu030.translation.page.imask; uae_u32 physical_addr = mmu030.atc[l].physical.addr&addr_mask; -#if MMU030_ATC_DBG_MSG +#if MMU030_ATC_DBG_MSG > 1 write_log(_T("ATC match(%i): page addr = %08X, index = %08X\n"), l, physical_addr, page_index); #endif @@ -2002,7 +2003,7 @@ static uaecptr mmu030_put_atc_generic(uaecptr addr, int l, uae_u32 fc, int flags uae_u32 addr_mask = mmu030.translation.page.imask; uae_u32 physical_addr = mmu030.atc[l].physical.addr & addr_mask; -#if MMU030_ATC_DBG_MSG +#if MMU030_ATC_DBG_MSG > 1 write_log(_T("ATC match(%i): page addr = %08X, index = %08X\n"), l, physical_addr, page_index); #endif @@ -2022,7 +2023,7 @@ static uae_u32 mmu030_get_atc_generic(uaecptr addr, int l, uae_u32 fc, int flags uae_u32 addr_mask = mmu030.translation.page.imask; uae_u32 physical_addr = mmu030.atc[l].physical.addr & addr_mask; -#if MMU030_ATC_DBG_MSG +#if MMU030_ATC_DBG_MSG > 1 write_log(_T("ATC match(%i): page addr = %08X, index = %08X\n"), l, physical_addr, page_index); #endif @@ -2269,8 +2270,8 @@ uae_u32 mmu030_get_ilong(uaecptr addr, uae_u32 fc) mmu030.mmu030_last_logical_address = 0xffffffff; #endif - mmu030_cache_state = CACHE_ENABLE_ALL; - if (fc != 7 && (!tt_enabled || !mmu030_match_ttr_access(addr,fc,false)) && mmu030.enabled) { + mmu030_cache_state = CACHE_ENABLE_ALL; + if (fc != 7 && (!tt_enabled || !mmu030_match_ttr_access(addr, fc, false)) && mmu030.enabled) { int atc_line_num = mmu030_logical_is_in_atc(addr, fc, false); if (atc_line_num >= 0) { addr = mmu030_get_i_atc(addr, atc_line_num, fc, MMU030_SSW_SIZE_L); @@ -2284,8 +2285,8 @@ uae_u32 mmu030_get_ilong(uaecptr addr, uae_u32 fc) return v; } -uae_u16 mmu030_get_iword(uaecptr addr, uae_u32 fc) { - +uae_u16 mmu030_get_iword(uaecptr addr, uae_u32 fc) +{ uae_u16 v; #if MMU_IPAGECACHE030 if (((addr & mmu030.translation.page.imask) | fc) == mmu030.mmu030_last_logical_address) { @@ -2301,8 +2302,8 @@ uae_u16 mmu030_get_iword(uaecptr addr, uae_u32 fc) { mmu030.mmu030_last_logical_address = 0xffffffff; #endif - mmu030_cache_state = CACHE_ENABLE_ALL; - if (fc != 7 && (!tt_enabled || !mmu030_match_ttr_access(addr,fc,false)) && mmu030.enabled) { + mmu030_cache_state = CACHE_ENABLE_ALL; + if (fc != 7 && (!tt_enabled || !mmu030_match_ttr_access(addr, fc, false)) && mmu030.enabled) { int atc_line_num = mmu030_logical_is_in_atc(addr, fc, false); if (atc_line_num >= 0) { addr = mmu030_get_i_atc(addr, atc_line_num, fc, MMU030_SSW_SIZE_W); @@ -3206,12 +3207,12 @@ uae_u32 REGPARAM2 get_disp_ea_020_mmu030c (uae_u32 base, int idx) // + whatever the instruction itself does. if (mmu030_state[1] & (1 << idx)) { - m68k_incpci (((mmu030_state[2] >> (idx * 4)) & 15) * 2); + m68k_incpci(((mmu030_state[2] >> (idx * 4)) & 15) * 2); return mmu030_disp_store[idx]; } oldidx = mmu030_idx; - dp = next_iword_mmu030c_state (); + dp = next_iword_mmu030c_state(); pcadd += 1; reg = (dp >> 12) & 15; @@ -3227,20 +3228,20 @@ uae_u32 REGPARAM2 get_disp_ea_020_mmu030c (uae_u32 base, int idx) regd = 0; if ((dp & 0x30) == 0x20) { - base += (uae_s32)(uae_s16) next_iword_mmu030c_state (); + base += (uae_s32)(uae_s16) next_iword_mmu030c_state(); pcadd += 1; } if ((dp & 0x30) == 0x30) { - base += next_ilong_mmu030c_state (); + base += next_ilong_mmu030c_state(); pcadd += 2; } if ((dp & 0x3) == 0x2) { - outer = (uae_s32)(uae_s16) next_iword_mmu030c_state (); + outer = (uae_s32)(uae_s16) next_iword_mmu030c_state(); pcadd += 1; } if ((dp & 0x3) == 0x3) { - outer = next_ilong_mmu030c_state (); + outer = next_ilong_mmu030c_state(); pcadd += 2; } @@ -3248,7 +3249,7 @@ uae_u32 REGPARAM2 get_disp_ea_020_mmu030c (uae_u32 base, int idx) base += regd; } if (dp & 0x3) { - base = get_long_mmu030c_state (base); + base = get_long_mmu030c_state(base); } if (dp & 0x4) { base += regd; @@ -3275,9 +3276,9 @@ void m68k_do_rte_mmu030c (uaecptr a7) uae_u16 sr = get_word_mmu030c(a7); uae_u32 pc = get_long_mmu030c(a7 + 2); - uae_u16 format = get_word_mmu030c (a7 + 6); + uae_u16 format = get_word_mmu030c(a7 + 6); uae_u16 frame = format >> 12; - uae_u16 ssw = get_word_mmu030c (a7 + 10); + uae_u16 ssw = get_word_mmu030c(a7 + 10); uae_u32 fault_addr = get_long_mmu030c(a7 + 16); // Data output buffer uae_u32 mmu030_data_buffer_out_v = get_long_mmu030c(a7 + 0x18); @@ -3423,6 +3424,15 @@ void m68k_do_rte_mmu030c (uaecptr a7) if ((ssw & MMU030_SSW_FB) && !(ssw & MMU030_SSW_RB)) { regs.prefetch020_valid[2] = 1; write_log(_T("Software fixed stage B! opcode = %04x\n"), regs.prefetch020[2]); +#if 0 + if (!regs.prefetch020_valid[0]) { + regs.prefetch020[0] = regs.prefetch020[1]; + regs.prefetch020[1] = regs.prefetch020[2]; + regs.prefetch020_valid[0] = regs.prefetch020_valid[1]; + regs.prefetch020_valid[1] = regs.prefetch020_valid[2]; + regs.prefetch020_valid[2] = 0; + } +#endif } if ((ssw & MMU030_SSW_FC) && !(ssw & MMU030_SSW_RC)) { regs.prefetch020_valid[1] = 1; @@ -3458,16 +3468,18 @@ void m68k_do_rte_mmu030c (uaecptr a7) m68k_setpci (pc); if (!(ssw & (MMU030_SSW_DF << 1))) { - if (!regs.prefetch020_valid[0] && regs.prefetch020_valid[2]) { - // Prefetch was software fixed, continue pipeline refill - fill_prefetch_030_ntx_continue(); - } else if (regs.prefetch020_valid[0] && regs.prefetch020_valid[1]) { - // Finished? + // software fixed? + if (((ssw & MMU030_SSW_FB) && !(ssw & MMU030_SSW_RB)) || ((ssw & MMU030_SSW_FC) && !(ssw & MMU030_SSW_RC))) { fill_prefetch_030_ntx_continue(); - } else if (mmu030_opcode == -1) { - // Previous branch instruction finished successfully but its pipeline refill - // step caused the exception, retry the refill, do not retry branch instruction. - fill_prefetch_030_ntx(); + } else { + // pipeline refill in progress? + if (mmu030_opcode == -1) { +#if MMU030_ALWAYS_FULL_PREFETCH + fill_prefetch_030_ntx(); +#else + fill_prefetch_030_ntx_continue(); +#endif + } } } @@ -3541,6 +3553,7 @@ void m68k_do_rte_mmu030c (uaecptr a7) if (mmu030_state[1] & MMU030_STATEFLAG1_LASTWRITE) { mmu030_retry = false; if (doprefetch) { + mmu030_opcode = -1; fill_prefetch_030_ntx(); } } diff --git a/gencpu.cpp b/gencpu.cpp index 1e7a0890..634e9018 100644 --- a/gencpu.cpp +++ b/gencpu.cpp @@ -420,6 +420,8 @@ static bool needmmufixup(void) case i_LINK: case i_RTD: case i_RTR: + case i_RTE: + case i_RTS: return false; } } @@ -530,17 +532,7 @@ static void get_prefetch_020_continue(void) { if (!isprefetch020()) return; - if (using_ce020) { - if (using_ce020 > 1) - out("continue_ce030_prefetch();\n"); - else - out("continue_ce020_prefetch();\n"); - } else { - if (using_prefetch_020 > 1) - out("continue_030_prefetch();\n"); - else - out("continue_020_prefetch();\n"); - } + get_prefetch_020(); } static void returntail (bool iswrite) @@ -6846,7 +6838,7 @@ static void gen_opcode (unsigned int opcode) } else { fill_prefetch_full_ntx(0); } - branch_inst = 1; + branch_inst = m68k_pc_total; next_cpu_level = cpu_level - 1; break; case i_RTD: @@ -6879,7 +6871,7 @@ static void gen_opcode (unsigned int opcode) } else { fill_prefetch_full(0); } - branch_inst = 1; + branch_inst = m68k_pc_total; next_level_040_to_030(); break; case i_LINK: @@ -7009,7 +7001,7 @@ static void gen_opcode (unsigned int opcode) } else { fill_prefetch_full(0); } - branch_inst = 1; + branch_inst = m68k_pc_total; if (!next_level_040_to_030()) { if (!next_level_020_to_010()) next_level_000(); @@ -7111,7 +7103,7 @@ static void gen_opcode (unsigned int opcode) } else { fill_prefetch_full(0); } - branch_inst = 1; + branch_inst = m68k_pc_total; tail_ce020_done = true; next_cpu_level = cpu_level - 1; break; @@ -7233,7 +7225,7 @@ static void gen_opcode (unsigned int opcode) } else { fill_prefetch_next_empty(); } - branch_inst = 1; + branch_inst = m68k_pc_total; next_level_040_to_030(); next_level_000(); } @@ -7282,7 +7274,7 @@ static void gen_opcode (unsigned int opcode) } else { fill_prefetch_full(0); } - branch_inst = 1; + branch_inst = m68k_pc_total; next_level_000(); break; case i_BSR: @@ -7380,7 +7372,7 @@ static void gen_opcode (unsigned int opcode) } else { fill_prefetch_full(0); } - branch_inst = 1; + branch_inst = m68k_pc_total; if (!next_level_040_to_030()) { if (!next_level_020_to_010()) next_level_000(); @@ -7472,7 +7464,7 @@ static void gen_opcode (unsigned int opcode) fill_prefetch_full_000_special(0, NULL); } insn_n_cycles = curi->size == sz_byte ? 8 : 12; - branch_inst = 1; + branch_inst = -m68k_pc_total; bccl_not68020: if (!next_level_040_to_030()) next_level_020_to_010(); @@ -7701,7 +7693,7 @@ bccl_not68020: clear_m68k_offset(); get_prefetch_020_continue(); fill_prefetch_full_000_special(-1, "if (!cctrue(%d)) {\nm68k_dreg(regs, srcreg) = (m68k_dreg(regs, srcreg) & ~0xffff) | (((src - 1)) & 0xffff);\n}\n", curi->cc); - branch_inst = 1; + branch_inst = -m68k_pc_total; if (!next_level_040_to_030()) { if (!next_level_020_to_010()) next_level_000(); @@ -9304,7 +9296,7 @@ static void generate_one_opcode (int rp, const char *extra) cputbltmp[opcode].disp020[1] = 0; if (genamode8r_offset[1] > 0) cputbltmp[opcode].disp020[1] = m68k_pc_total - genamode8r_offset[1] + 2; - cputbltmp[opcode].branch = branch_inst; + cputbltmp[opcode].branch = branch_inst / 2; if (m68k_pc_total > 0) out("/* %d %d,%d %c */\n", diff --git a/include/cpummu030.h b/include/cpummu030.h index 13691ac1..417aa60a 100644 --- a/include/cpummu030.h +++ b/include/cpummu030.h @@ -532,7 +532,7 @@ STATIC_INLINE uae_u32 get_ilong_mmu030_state (int o) uae_u32 v; uae_u32 addr = m68k_getpci () + o; ACCESS_CHECK_GET - v = uae_mmu030_get_ilong (addr); + v = uae_mmu030_get_ilong(addr); ACCESS_EXIT_GET return v; } @@ -551,7 +551,7 @@ STATIC_INLINE uae_u32 next_ilong_mmu030_state (void) uae_u32 v; uae_u32 addr = m68k_getpci (); ACCESS_CHECK_GET_PC(4); - v = uae_mmu030_get_ilong (addr); + v = uae_mmu030_get_ilong(addr); m68k_incpci (4); ACCESS_EXIT_GET return v; @@ -860,10 +860,8 @@ STATIC_INLINE uae_u32 get_iword_mmu030c_state (int o) STATIC_INLINE uae_u32 get_ilong_mmu030c_state (int o) { uae_u32 v; - ACCESS_CHECK_GET; - v = get_word_030_prefetch(o + 0) << 16; - v |= get_word_030_prefetch(o + 2); - ACCESS_EXIT_GET + v = get_iword_mmu030c_state(o + 0) << 16; + v |= get_iword_mmu030c_state(o + 2) & 0xffff; return v; } STATIC_INLINE uae_u32 get_iword_mmu030c_opcode_state(int o) @@ -884,11 +882,8 @@ STATIC_INLINE uae_u32 next_iword_mmu030c_state (void) STATIC_INLINE uae_u32 next_ilong_mmu030c_state (void) { uae_u32 v; - ACCESS_CHECK_GET_PC(4); - v = get_word_030_prefetch(0) << 16; - v |= get_word_030_prefetch(2); - m68k_incpci (4); - ACCESS_EXIT_GET + v = next_iword_mmu030c_state() << 16; + v |= next_iword_mmu030c_state() & 0xffff; return v; } diff --git a/include/newcpu.h b/include/newcpu.h index 061fdda1..ecd781ff 100644 --- a/include/newcpu.h +++ b/include/newcpu.h @@ -62,7 +62,7 @@ struct cputbl { uae_u16 opcode; uae_s8 length; uae_s8 disp020[2]; - uae_u8 branch; + uae_s8 branch; }; #ifdef JIT diff --git a/newcpu.cpp b/newcpu.cpp index 9214dbfd..b85b1606 100644 --- a/newcpu.cpp +++ b/newcpu.cpp @@ -120,7 +120,7 @@ struct cputbl_data { uae_s16 length; uae_s8 disp020[2]; - uae_u8 branch; + uae_s8 branch; }; static struct cputbl_data cpudatatbl[65536]; @@ -7765,7 +7765,7 @@ static void pipeline_020(uaecptr pc) #endif // illegal instructions, TRAP, TRAPV, A-line, F-line don't stop prefetches int branch = cpudatatbl[w].branch; - if (regs.pipeline_pos > 0 && branch) { + if (regs.pipeline_pos > 0 && branch > 0) { // Short branches (Bcc.s) still do one more prefetch. #if 0 // RTS and other unconditional single opcode instruction stop immediately. diff --git a/newcpu_common.cpp b/newcpu_common.cpp index 9a791862..ec19665a 100644 --- a/newcpu_common.cpp +++ b/newcpu_common.cpp @@ -1566,34 +1566,34 @@ void Exception_build_stack_frame(uae_u32 oldpc, uae_u32 currpc, uae_u32 ssw, int // used when instruction's last write causes bus fault m68k_areg(regs, 7) -= 4; if (format == 0xb) { - x_put_long(m68k_areg(regs, 7), mmu030_disp_store[0]); + x_put_long(m68k_areg(regs, 7), mmu030_disp_store[0]); // 28 0x1c } else { uae_u32 ps = (regs.prefetch020_valid[0] ? 1 : 0) | (regs.prefetch020_valid[1] ? 2 : 0) | (regs.prefetch020_valid[2] ? 4 : 0); ps |= ((regs.pipeline_r8[0] & 7) << 8); ps |= ((regs.pipeline_r8[1] & 7) << 11); ps |= ((regs.pipeline_pos & 15) << 16); ps |= ((regs.pipeline_stop & 15) << 20); - x_put_long(m68k_areg(regs, 7), ps); + x_put_long(m68k_areg(regs, 7), ps); // 28 0x1c } m68k_areg(regs, 7) -= 4; // Data output buffer = value that was going to be written - x_put_long(m68k_areg(regs, 7), regs.wb3_data); + x_put_long(m68k_areg(regs, 7), regs.wb3_data); // 24 0x18 m68k_areg(regs, 7) -= 4; if (format == 0xb) { - x_put_long(m68k_areg(regs, 7), (mmu030_opcode & 0xffff) | (regs.prefetch020[0] << 16)); // Internal register (opcode storage) + x_put_long(m68k_areg(regs, 7), (mmu030_opcode & 0xffff) | (regs.prefetch020[0] << 16)); // Internal register (opcode storage) 20 0x14 } else { - x_put_long(m68k_areg(regs, 7), regs.irc | (regs.prefetch020[0] << 16)); // Internal register (opcode storage) + x_put_long(m68k_areg(regs, 7), regs.irc | (regs.prefetch020[0] << 16)); // Internal register (opcode storage) 20 0x14 } m68k_areg(regs, 7) -= 4; - x_put_long(m68k_areg(regs, 7), regs.mmu_fault_addr); // data cycle fault address + x_put_long(m68k_areg(regs, 7), regs.mmu_fault_addr); // data cycle fault address 16 0x10 m68k_areg(regs, 7) -= 2; - x_put_word(m68k_areg(regs, 7), regs.prefetch020[2]); // Instr. pipe stage B + x_put_word(m68k_areg(regs, 7), regs.prefetch020[2]); // Instr. pipe stage B 14 0x0e m68k_areg(regs, 7) -= 2; - x_put_word(m68k_areg(regs, 7), regs.prefetch020[1]); // Instr. pipe stage C + x_put_word(m68k_areg(regs, 7), regs.prefetch020[1]); // Instr. pipe stage C 12 0x0c m68k_areg(regs, 7) -= 2; - x_put_word(m68k_areg(regs, 7), ssw); + x_put_word(m68k_areg(regs, 7), ssw); // 10 0x0a m68k_areg(regs, 7) -= 2; - x_put_word(m68k_areg(regs, 7), regs.wb2_address); // = mmu030_state[1]); + x_put_word(m68k_areg(regs, 7), regs.wb2_address); // = mmu030_state[1]); 8 0x08 break; default: write_log(_T("Unknown exception stack frame format: %X\n"), format);