From: Toni Wilen Date: Mon, 6 Jul 2015 15:58:52 +0000 (+0300) Subject: Do not prefetch opcode words if instruction is going to branch. X-Git-Tag: 3200~159 X-Git-Url: https://git.unchartedbackwaters.co.uk/w/?a=commitdiff_plain;h=51e810a3ebf2ce4e6352cac47e30da8e9d3f5455;p=francis%2Fwinuae.git Do not prefetch opcode words if instruction is going to branch. --- diff --git a/gencpu.cpp b/gencpu.cpp index 21500c42..d265be2d 100644 --- a/gencpu.cpp +++ b/gencpu.cpp @@ -96,6 +96,7 @@ static const char *dstblrmw, *dstwlrmw, *dstllrmw; static const char *srcbrmw, *srcwrmw, *srclrmw; static const char *dstbrmw, *dstwrmw, *dstlrmw; static const char *prefetch_long, *prefetch_word; +static const char *prefetch_long_buffer, *prefetch_word_buffer; static const char *srcli, *srcwi, *srcbi, *nextl, *nextw; static const char *srcld, *dstld; static const char *srcwd, *dstwd; @@ -467,7 +468,10 @@ static void gen_nextilong2 (const char *type, const char *name, int flags, int m printf ("\t%s %s;\n", type, name); add_mmu040_movem (movem); if (using_ce020) { - printf ("\t%s = %s (%d);\n", name, prefetch_long, r); + if (flags & GF_NOREFILL) + printf("\t%s = %s (%d);\n", name, prefetch_long_buffer, r); + else + printf("\t%s = %s (%d);\n", name, prefetch_long, r); count_read += 2; } else if (using_ce) { /* we must do this because execution order of (something | something2) is not defined */ @@ -512,7 +516,10 @@ static const char *gen_nextiword (int flags) m68k_pc_offset += 2; if (using_ce020) { - sprintf (buffer, "%s (%d)", prefetch_word, r); + if (flags & GF_NOREFILL) + sprintf(buffer, "%s (%d)", prefetch_word_buffer, r); + else + sprintf(buffer, "%s (%d)", prefetch_word, r); count_read++; } else if (using_ce) { if (flags & GF_NOREFILL) { @@ -545,7 +552,10 @@ static const char *gen_nextibyte (int flags) m68k_pc_offset += 2; if (using_ce020 || using_prefetch_020) { - sprintf (buffer, "(uae_u8)%s (%d)", prefetch_word, r); + if (flags & GF_NOREFILL) + sprintf(buffer, "(uae_u8)%s (%d)", prefetch_word_buffer, r); + else + sprintf(buffer, "(uae_u8)%s (%d)", prefetch_word, r); count_read++; } else if (using_ce) { if (flags & GF_NOREFILL) { @@ -2679,6 +2689,8 @@ static void resetvars (void) got_ea_ce020 = false; prefetch_long = NULL; + prefetch_word_buffer = NULL; + prefetch_long_buffer = NULL; srcli = NULL; srcbi = NULL; disp000 = "get_disp_ea_000"; @@ -2735,6 +2747,8 @@ static void resetvars (void) disp020 = "x_get_disp_ea_ce020"; prefetch_word = "get_word_ce020_prefetch"; prefetch_long = "get_long_ce020_prefetch"; + prefetch_word_buffer = "get_word_ce020_prefetch_buffer"; + prefetch_long_buffer = "get_long_ce020_prefetch_buffer"; srcli = "x_get_ilong"; srcwi = "x_get_iword"; srcbi = "x_get_ibyte"; @@ -2752,6 +2766,8 @@ static void resetvars (void) disp020 = "x_get_disp_ea_ce030"; prefetch_long = "get_long_ce030_prefetch"; prefetch_word = "get_word_ce030_prefetch"; + prefetch_word_buffer = "get_word_ce030_prefetch_buffer"; + prefetch_long_buffer = "get_long_ce030_prefetch_buffer"; srcli = "x_get_ilong"; srcwi = "x_get_iword"; srcbi = "x_get_ibyte"; @@ -2785,6 +2801,8 @@ static void resetvars (void) disp020 = "x_get_disp_ea_020"; prefetch_word = "get_word_020_prefetch"; prefetch_long = "get_long_020_prefetch"; + prefetch_word_buffer = "get_word_020_prefetch_buffer"; + prefetch_long_buffer = "get_long_020_prefetch_buffer"; srcli = "x_get_ilong"; srcwi = "x_get_iword"; srcbi = "x_get_ibyte"; @@ -2967,6 +2985,10 @@ static void resetvars (void) dstwlrmw = dstw; dstllrmw = dstl; } + if (!prefetch_word_buffer) + prefetch_word_buffer = prefetch_word; + if (!prefetch_long_buffer) + prefetch_long_buffer = prefetch_long; } @@ -4034,7 +4056,7 @@ static void gen_opcode (unsigned int opcode) next_cpu_level = 1; } } - genamode (curi, curi->smode, "srcreg", curi->size, "src", 1, 0, GF_AA | GF_NOREFILL); + genamode (curi, curi->smode, "srcreg", curi->size, "src", 1, 0, GF_AA | (cpu_level < 2 ? GF_NOREFILL : 0)); addcycles000 (2); printf ("\tif (!cctrue (%d)) goto didnt_jump;\n", curi->cc); if (using_exception_3) { @@ -4110,8 +4132,8 @@ bccl_not68020: // cc false, counter not expired: idle cycle, prefetch tail_ce020_done = true; genamodedual (curi, - curi->smode, "srcreg", curi->size, "src", 1, GF_AA | GF_NOREFILL, - curi->dmode, "dstreg", curi->size, "offs", 1, GF_AA | GF_NOREFILL); + curi->smode, "srcreg", curi->size, "src", 1, GF_AA | (cpu_level < 2 ? GF_NOREFILL : 0), + curi->dmode, "dstreg", curi->size, "offs", 1, GF_AA | (cpu_level < 2 ? GF_NOREFILL : 0)); //genamode (curi, curi->smode, "srcreg", curi->size, "src", 1, 0, GF_AA | GF_NOREFILL); //genamode (curi, curi->dmode, "dstreg", curi->size, "offs", 1, 0, GF_AA | GF_NOREFILL); printf ("\tuaecptr oldpc = %s;\n", getpc); diff --git a/newcpu.cpp b/newcpu.cpp index c345798b..749ed7de 100644 --- a/newcpu.cpp +++ b/newcpu.cpp @@ -3823,7 +3823,7 @@ static void m68k_run_1 (void) exit = true; } regs.ipl = regs.ipl_pin; - if (!currprefs.cpu_compatible || (currprefs.cpu_cycle_exact && currprefs.cpu_model <= 68000)) + if (!currprefs.cpu_compatible || (currprefs.cpu_cycle_exact && currprefs.cpu_model <= 68010)) exit = true; } } CATCH (prb) { @@ -3937,7 +3937,7 @@ cont: exit = true; } - if (!currprefs.cpu_cycle_exact || currprefs.cpu_model > 68000) + if (!currprefs.cpu_cycle_exact || currprefs.cpu_model > 68010) exit = true; } } CATCH (prb) { @@ -6354,6 +6354,25 @@ uae_u32 get_word_ce020_prefetch (int o) return v; } +uae_u32 get_word_ce020_prefetch_buffer(int o) +{ + uae_u32 pc = m68k_getpc() + o; + uae_u32 v; + + if (pc & 2) { + v = regs.prefetch020[0] & 0xffff; + regs.prefetch020[0] = regs.prefetch020[1]; + //fill_icache020(pc + 2 + 4, mem_access_delay_longi_read_ce020); + //regs.prefetch020[1] = regs.cacheholdingdata020; + regs.db = regs.prefetch020[0] >> 16; + } else { + v = regs.prefetch020[0] >> 16; + regs.db = regs.prefetch020[1] >> 16; + } + do_cycles_ce020_internal(2); + return v; +} + uae_u32 get_word_020_prefetch (int o) { uae_u32 pc = m68k_getpc () + o; @@ -6874,6 +6893,23 @@ uae_u32 get_word_ce030_prefetch (int o) return v; } +uae_u32 get_word_ce030_prefetch_buffer(int o) +{ + uae_u32 pc = m68k_getpc() + o; + uae_u32 v; + + if (pc & 2) { + v = regs.prefetch020[0] & 0xffff; + regs.prefetch020[0] = regs.prefetch020[1]; + //fill_icache030(pc + 2 + 4); + //regs.prefetch020[1] = regs.cacheholdingdata020; + } else { + v = regs.prefetch020[0] >> 16; + } + do_cycles_ce020_internal(2); + return v; +} + uae_u32 get_word_icache030(uaecptr addr) { fill_icache030(addr);