From 2546affb23a952ddc16e7ec0e4207afb729884d0 Mon Sep 17 00:00:00 2001 From: Toni Wilen Date: Tue, 10 Jan 2017 20:25:44 +0200 Subject: [PATCH] T0 trace update. --- gencpu.cpp | 134 +++++++++++++++++++++++++++++++---------------- include/newcpu.h | 17 +++--- newcpu.cpp | 129 +++++++++++++++++++++++++++------------------ 3 files changed, 175 insertions(+), 105 deletions(-) diff --git a/gencpu.cpp b/gencpu.cpp index 541836c2..ee2a757a 100644 --- a/gencpu.cpp +++ b/gencpu.cpp @@ -587,13 +587,20 @@ static const char *gen_nextibyte (int flags) return buffer; } -static void makefromsr (void) +static void makefromsr(void) { printf ("\tMakeFromSR();\n"); if (using_ce || isce020()) printf ("\tregs.ipl_pin = intlev ();\n"); } +static void makefromsr_t0(void) +{ + printf ("\tMakeFromSR_T0();\n"); + if (using_ce || isce020()) + printf ("\tregs.ipl_pin = intlev ();\n"); +} + static void check_ipl (void) { if (ipl_fetched) @@ -664,6 +671,41 @@ static void fill_prefetch_1 (int o) } } +static void fill_prefetch_full_2 (void) +{ + if (using_prefetch) { + fill_prefetch_1 (0); + irc2ir (); + fill_prefetch_1 (2); + } else if (isprefetch020()) { + did_prefetch = 2; + total_ce020 -= 4; + returntail (false); + if (cpu_level >= 3) + printf ("\tfill_prefetch_030();\n"); + else if (cpu_level == 2) + printf ("\tfill_prefetch_020();\n"); + } +} + +// don't check trace bits +static void fill_prefetch_full_ntx (void) +{ + if (using_prefetch) { + fill_prefetch_1 (0); + irc2ir (); + fill_prefetch_1 (2); + } else if (isprefetch020()) { + did_prefetch = 2; + total_ce020 -= 4; + returntail (false); + if (cpu_level >= 3) + printf ("\tfill_prefetch_030_ntx();\n"); + else if (cpu_level == 2) + printf ("\tfill_prefetch_020_ntx();\n"); + } +} +// check trace bits static void fill_prefetch_full (void) { if (using_prefetch) { @@ -675,9 +717,11 @@ static void fill_prefetch_full (void) total_ce020 -= 4; returntail (false); if (cpu_level >= 3) - printf ("\tfill_prefetch_030 ();\n"); + printf ("\tfill_prefetch_030();\n"); else if (cpu_level == 2) - printf ("\tfill_prefetch_020 ();\n"); + printf ("\tfill_prefetch_020();\n"); + } else if (!using_prefetch_020 && cpu_level >= 2) { + printf("\tif(regs.t0) check_t0_trace();\n"); } } @@ -692,8 +736,10 @@ static void fill_prefetch_full_000 (void) // 68020+ static void fill_prefetch_full_020 (void) { - if (!using_prefetch_020) + if (!using_prefetch_020) { + printf("\tif(regs.t0) check_t0_trace();\n"); return; + } fill_prefetch_full (); } @@ -3101,14 +3147,10 @@ static void gen_opcode (unsigned int opcode) printf ("\tsrc &= 0xFF;\n"); } addcycles000 (8); - if (cpu_level <= 1) { - sync_m68k_pc (); - fill_prefetch_full (); - } else { - fill_prefetch_next (); - } printf ("\tregs.sr %c= src;\n", curi->mnemo == i_EORSR ? '^' : '|'); - makefromsr (); + makefromsr_t0(); + sync_m68k_pc (); + fill_prefetch_full_ntx(); break; case i_ANDSR: printf ("\tMakeSR ();\n"); @@ -3117,14 +3159,10 @@ static void gen_opcode (unsigned int opcode) printf ("\tsrc |= 0xFF00;\n"); } addcycles000 (8); - if (cpu_level <= 1) { - sync_m68k_pc (); - fill_prefetch_full (); - } else { - fill_prefetch_next (); - } printf ("\tregs.sr &= src;\n"); - makefromsr (); + makefromsr_t0(); + sync_m68k_pc (); + fill_prefetch_full_ntx(); break; case i_SUB: { @@ -3641,14 +3679,10 @@ static void gen_opcode (unsigned int opcode) addcycles000 (4); printf ("\tregs.sr = src;\n"); } - makefromsr (); - if (cpu_level <= 1) { - // 68000 does 2xprefetch - sync_m68k_pc (); - fill_prefetch_full (); - } else { - fill_prefetch_next (); - } + makefromsr_t0(); + // does full prefetch because S-bit change may change memory mapping under the CPU + sync_m68k_pc (); + fill_prefetch_full_ntx(); break; case i_SWAP: genamode (curi, curi->smode, "srcreg", sz_long, "src", 1, 0, 0); @@ -3706,7 +3740,7 @@ static void gen_opcode (unsigned int opcode) genamode (curi, curi->smode, "srcreg", curi->size, "src", 1, 0, 0); gen_set_fault_pc (); sync_m68k_pc (); - printf ("\tException (src + 32);\n"); + printf ("\tException_cpu(src + 32);\n"); did_prefetch = 1; clear_m68k_offset(); break; @@ -3742,7 +3776,7 @@ static void gen_opcode (unsigned int opcode) printf ("\tregs.sr = src;\n"); } addcycles000(2 * 4); - makefromsr (); + makefromsr(); printf ("\tm68k_setstopped ();\n"); sync_m68k_pc (); // STOP does not prefetch anything @@ -3755,11 +3789,11 @@ static void gen_opcode (unsigned int opcode) printf ("\tsr = %s (4);\n", srcwi); printf ("\tif (!(sr & 0x8000)) { Exception (8); goto %s; }\n", endlabelstr); printf ("\tregs.sr = sr;\n"); - makefromsr (); + makefromsr(); printf ("\tm68k_setstopped();\n"); m68k_pc_offset += 4; sync_m68k_pc (); - fill_prefetch_full (); + fill_prefetch_full_ntx(); break; case i_RTE: addop_ce020 (curi, 0); @@ -3773,7 +3807,7 @@ static void gen_opcode (unsigned int opcode) printf ("\t\tgoto %s;\n", endlabelstr); printf ("\t}\n"); setpc ("pc"); - makefromsr (); + makefromsr(); } else if (cpu_level == 1 && using_prefetch) { int old_brace_level = n_braces; printf ("\tuae_u16 newsr; uae_u32 newpc;\n"); @@ -3790,11 +3824,11 @@ static void gen_opcode (unsigned int opcode) printf ("\t\tnewsr = sr; newpc = pc;\n"); printf ("\t\tif (frame == 0x0) { m68k_areg (regs, 7) += offset; break; }\n"); printf ("\t\telse if (frame == 0x8) { m68k_areg (regs, 7) += offset + 50; break; }\n"); - printf ("\t\telse { m68k_areg (regs, 7) += offset; Exception (14); goto %s; }\n", endlabelstr); + printf ("\t\telse { m68k_areg (regs, 7) += offset; Exception_cpu(14); goto %s; }\n", endlabelstr); printf ("\t\tregs.sr = newsr; MakeFromSR ();\n}\n"); pop_braces (old_brace_level); printf ("\tregs.sr = newsr;\n"); - makefromsr (); + makefromsr(); printf ("\tif (newpc & 1) {\n"); printf ("\t\texception3i (0x%04X, newpc);\n", opcode); printf ("\t\tgoto %s;\n", endlabelstr); @@ -3840,14 +3874,14 @@ static void gen_opcode (unsigned int opcode) printf ("\t\telse if (frame == 0xa) { m68k_areg (regs, 7) += offset + 24; break; }\n"); printf ("\t\telse if (frame == 0xb) { m68k_areg (regs, 7) += offset + 84; break; }\n"); } - printf ("\t\telse { m68k_areg (regs, 7) += offset; Exception (14); goto %s; }\n", endlabelstr); + printf ("\t\telse { m68k_areg (regs, 7) += offset; Exception_cpu(14); goto %s; }\n", endlabelstr); printf ("\t\tregs.sr = newsr;\n"); - makefromsr (); + makefromsr_t0(); printf ("}\n"); pop_braces (old_brace_level); printf ("\tregs.sr = newsr;\n"); addcycles_ce020 (4); - makefromsr (); + makefromsr_t0(); printf ("\tif (newpc & 1) {\n"); printf ("\t\texception3i (0x%04X, newpc);\n", opcode); printf ("\t\tgoto %s;\n", endlabelstr); @@ -3859,7 +3893,7 @@ static void gen_opcode (unsigned int opcode) /* PC is set and prefetch filled. */ clear_m68k_offset(); tail_ce020_done = true; - fill_prefetch_full (); + fill_prefetch_full_ntx(); branch_inst = 1; break; case i_RTD: @@ -3957,7 +3991,7 @@ static void gen_opcode (unsigned int opcode) sync_m68k_pc (); fill_prefetch_next (); printf ("\tif (GET_VFLG ()) {\n"); - printf ("\t\tException (7);\n"); + printf ("\t\tException_cpu(7);\n"); printf ("\t\tgoto %s;\n", endlabelstr); printf ("\t}\n"); need_endlabel = 1; @@ -3970,7 +4004,7 @@ static void gen_opcode (unsigned int opcode) printf ("\tregs.sr &= 0xFF00; sr &= 0xFF;\n"); printf ("\tregs.sr |= sr;\n"); setpc ("pc"); - makefromsr (); + makefromsr(); printf ("\tif (%s & 1) {\n", getpc); printf ("\t\tuaecptr faultpc = %s;\n", getpc); setpc ("oldpc"); @@ -4253,7 +4287,7 @@ bccl_not68020: if (cpu_level > 1) printf ("\t\tdivbyzero_special (0, dst);\n"); incpc ("%d", m68k_pc_offset); - printf ("\t\tException (5);\n"); + printf ("\t\tException_cpu(5);\n"); printf ("\t\tgoto %s;\n", endlabelstr); printf ("\t} else {\n"); printf ("\t\tuae_u32 newv = (uae_u32)dst / (uae_u32)(uae_u16)src;\n"); @@ -4297,7 +4331,7 @@ bccl_not68020: if (cpu_level > 1) printf ("\t\tdivbyzero_special (1, dst);\n"); incpc ("%d", m68k_pc_offset); - printf ("\t\tException (5);\n"); + printf ("\t\tException_cpu(5);\n"); printf ("\t\tgoto %s;\n", endlabelstr); printf ("\t}\n"); printf ("\tCLEAR_CZNV ();\n"); @@ -4394,13 +4428,13 @@ bccl_not68020: addcycles000 (4); printf ("\tif (dst > src) {\n"); printf ("\t\tSET_NFLG (0);\n"); - printf ("\t\tException (6);\n"); + printf ("\t\tException_cpu(6);\n"); printf ("\t\tgoto %s;\n", endlabelstr); printf ("\t}\n"); addcycles000 (2); printf ("\tif ((uae_s32)dst < 0) {\n"); printf ("\t\tSET_NFLG (1);\n"); - printf ("\t\tException (6);\n"); + printf ("\t\tException_cpu(6);\n"); printf ("\t\tgoto %s;\n", endlabelstr); printf ("\t}\n"); fill_prefetch_next (); @@ -4428,7 +4462,7 @@ bccl_not68020: } printf ("\tSET_ZFLG (upper == reg || lower == reg);\n"); printf ("\tSET_CFLG_ALWAYS (lower <= upper ? reg < lower || reg > upper : reg > upper || reg < lower);\n"); - printf ("\tif ((extra & 0x800) && GET_CFLG ()) { Exception (6); goto %s; }\n}\n", endlabelstr); + printf ("\tif ((extra & 0x800) && GET_CFLG ()) { Exception_cpu(6); goto %s; }\n}\n", endlabelstr); need_endlabel = 1; break; @@ -5026,7 +5060,7 @@ bccl_not68020: if (curi->smode != am_unknown && curi->smode != am_illg) genamode (curi, curi->smode, "srcreg", curi->size, "dummy", 1, 0, 0); fill_prefetch_0 (); - printf ("\tif (cctrue (%d)) { Exception (7); goto %s; }\n", curi->cc, endlabelstr); + printf ("\tif (cctrue (%d)) { Exception_cpu(7); goto %s; }\n", curi->cc, endlabelstr); need_endlabel = 1; break; case i_DIVL: @@ -5217,6 +5251,11 @@ bccl_not68020: printf ("\t\tgoto %s;\n", endlabelstr); printf ("\t}\n"); need_endlabel = 1; + } else { + printf ("\tif (regs.fp_branch) {\n"); + printf ("\t\tregs.fp_branch = false;\n"); + printf ("\t\tif(regs.t0) check_t0_trace();\n"); + printf ("\t}\n"); } break; case i_FScc: @@ -5258,6 +5297,11 @@ bccl_not68020: printf ("\t\tgoto %s;\n", endlabelstr); printf ("\t}\n"); need_endlabel = 1; + } else { + printf ("\tif (regs.fp_branch) {\n"); + printf ("\t\tregs.fp_branch = false;\n"); + printf ("\t\tif(regs.t0) check_t0_trace();\n"); + printf ("\t}\n"); } break; case i_FSAVE: diff --git a/include/newcpu.h b/include/newcpu.h index 13c83f96..30ebb0dd 100644 --- a/include/newcpu.h +++ b/include/newcpu.h @@ -13,9 +13,7 @@ #include "readcpu.h" #include "machdep/m68k.h" #include "events.h" -#ifdef WITH_SOFTFLOAT -#include -#endif +#include #ifndef SET_CFLG @@ -145,9 +143,7 @@ extern struct mmufixup mmufixup[2]; typedef struct { fptype fp; -#ifdef WITH_SOFTFLOAT floatx80 fpx; -#endif } fpdata; struct regstruct @@ -503,6 +499,7 @@ STATIC_INLINE void m68k_setpc_normal(uaecptr pc) } } +extern void check_t0_trace(void); extern void write_dcache030(uaecptr, uae_u32, int); extern uae_u32 read_dcache030(uaecptr, int); extern uae_u32 get_word_icache030(uaecptr addr); @@ -550,8 +547,10 @@ extern void set_cpu_caches (bool flush); extern void flush_cpu_caches(bool flush); extern void flush_cpu_caches_040(uae_u16 opcode); extern void REGPARAM3 MakeSR (void) REGPARAM; -extern void REGPARAM3 MakeFromSR (void) REGPARAM; +extern void REGPARAM3 MakeFromSR(void) REGPARAM; +extern void REGPARAM3 MakeFromSR_T0(void) REGPARAM; extern void REGPARAM3 Exception (int) REGPARAM; +extern void REGPARAM3 Exception_cpu(int) REGPARAM; extern void REGPARAM3 ExceptionL (int, uaecptr) REGPARAM; extern void NMI (void); extern void NMI_delayed (void); @@ -608,8 +607,10 @@ extern void cpu_change(int newmodel); extern void cpu_fallback(int mode); extern void fill_prefetch (void); -extern void fill_prefetch_020 (void); -extern void fill_prefetch_030 (void); +extern void fill_prefetch_020_ntx(void); +extern void fill_prefetch_030_ntx(void); +extern void fill_prefetch_020(void); +extern void fill_prefetch_030(void); #define CPU_OP_NAME(a) op ## a diff --git a/newcpu.cpp b/newcpu.cpp index e94d165a..aaecfc1b 100644 --- a/newcpu.cpp +++ b/newcpu.cpp @@ -1788,7 +1788,7 @@ static uaecptr ShowEA (void *f, uaecptr pc, uae_u16 opcode, int reg, amodes mode { fpdata fp; to_single(&fp, get_ilong_debug(pc)); - _stprintf(buffer, _T("#%e"), fp.fp); + _stprintf(buffer, _T("#%s"), fp_print(&fp)); pc += 4; } break; @@ -1796,7 +1796,7 @@ static uaecptr ShowEA (void *f, uaecptr pc, uae_u16 opcode, int reg, amodes mode { fpdata fp; to_double(&fp, get_ilong_debug(pc), get_ilong_debug(pc + 4)); - _stprintf(buffer, _T("#%e"), fp.fp); + _stprintf(buffer, _T("#%s"), fp_print(&fp)); pc += 8; } break; @@ -1804,11 +1804,7 @@ static uaecptr ShowEA (void *f, uaecptr pc, uae_u16 opcode, int reg, amodes mode { fpdata fp; to_exten(&fp, get_ilong_debug(pc), get_ilong_debug(pc + 4), get_ilong_debug(pc + 8)); -#if USE_LONG_DOUBLE - _stprintf(buffer, _T("#%Le"), fp.fp); -#else - _stprintf(buffer, _T("#%e"), fp.fp); -#endif + _stprintf(buffer, _T("#%s"), fp_print(&fp)); pc += 12; break; } @@ -2040,6 +2036,12 @@ static void m68k_unset_stop(void) cpu_last_stop_vpos = vpos; } +static void activate_trace(void) +{ + unset_special (SPCFLAG_TRACE); + set_special (SPCFLAG_DOTRACE); +} + void REGPARAM2 MakeSR (void) { regs.sr = ((regs.t1 << 15) | (regs.t0 << 14) @@ -2061,10 +2063,12 @@ static void SetSR (uae_u16 sr) SET_CFLG (regs.sr & 1); } -void REGPARAM2 MakeFromSR (void) +static void MakeFromSR_x(int t0trace) { int oldm = regs.m; int olds = regs.s; + int oldt0 = regs.t0; + int oldt1 = regs.t1; SET_XFLG ((regs.sr >> 4) & 1); SET_NFLG ((regs.sr >> 3) & 1); @@ -2124,12 +2128,28 @@ void REGPARAM2 MakeFromSR (void) mmu_set_super (regs.s != 0); doint (); - if (regs.t1 || regs.t0) + if (regs.t1 || regs.t0) { set_special (SPCFLAG_TRACE); - else + } else { /* Keep SPCFLAG_DOTRACE, we still want a trace exception for SR-modifying instructions (including STOP). */ unset_special (SPCFLAG_TRACE); + } + // Stop SR-modification does not generate T0 + // If this SR modification set Tx bit, no trace until next instruction. + if ((oldt0 && t0trace && currprefs.cpu_model >= 68020) || oldt1) { + // Always trace if Tx bits were already set, even if this SR modification cleared them. + activate_trace(); + } +} + +void REGPARAM2 MakeFromSR_T0(void) +{ + MakeFromSR_x(1); +} +void REGPARAM2 MakeFromSR(void) +{ + MakeFromSR_x(0); } static void exception_check_trace (int nr) @@ -2972,6 +2992,15 @@ static void ExceptionX (int nr, uaecptr address) } } +void REGPARAM2 Exception_cpu(int nr) +{ + bool t0 = currprefs.cpu_model >= 68020 && regs.t0; + ExceptionX (nr, -1); + // check T0 trace + if (t0) { + activate_trace(); + } +} void REGPARAM2 Exception (int nr) { ExceptionX (nr, -1); @@ -3538,40 +3567,14 @@ void mmu_op (uae_u32 opcode, uae_u32 extra) #endif -static uaecptr last_trace_ad = 0; - static void do_trace (void) { if (regs.t0 && currprefs.cpu_model >= 68020) { - uae_u16 opcode; - /* should also include TRAP, CHK, SR modification FPcc */ - /* probably never used so why bother */ - /* We can afford this to be inefficient... */ - m68k_setpc_normal (m68k_getpc ()); - fill_prefetch (); - opcode = x_get_word (regs.pc); - if (opcode == 0x4e73 /* RTE */ - || opcode == 0x4e74 /* RTD */ - || opcode == 0x4e75 /* RTS */ - || opcode == 0x4e77 /* RTR */ - || opcode == 0x4e76 /* TRAPV */ - || (opcode & 0xffc0) == 0x4e80 /* JSR */ - || (opcode & 0xffc0) == 0x4ec0 /* JMP */ - || (opcode & 0xff00) == 0x6100 /* BSR */ - || ((opcode & 0xf000) == 0x6000 /* Bcc */ - && cctrue ((opcode >> 8) & 0xf)) - || ((opcode & 0xf0f0) == 0x5050 /* DBcc */ - && !cctrue ((opcode >> 8) & 0xf) - && (uae_s16)m68k_dreg (regs, opcode & 7) != 0)) - { - last_trace_ad = m68k_getpc (); - unset_special (SPCFLAG_TRACE); - set_special (SPCFLAG_DOTRACE); - } - } else if (regs.t1) { - last_trace_ad = m68k_getpc (); - unset_special (SPCFLAG_TRACE); - set_special (SPCFLAG_DOTRACE); + // this is obsolete + return; + } + if (regs.t1) { + activate_trace(); } } @@ -7240,15 +7243,6 @@ static void pipeline_020(uae_u16 w, uaecptr pc) } } -// Not exactly right, requires logic analyzer checks. -void continue_ce020_prefetch(void) -{ - fill_prefetch_020(); -} -void continue_020_prefetch(void) -{ - fill_prefetch_020(); -} #endif uae_u32 get_word_ce020_prefetch (int o) @@ -8238,7 +8232,15 @@ void flush_dcache (uaecptr addr, int size) } } -void fill_prefetch_030 (void) +void check_t0_trace(void) +{ + if (regs.t0 && currprefs.cpu_model >= 68020) { + unset_special (SPCFLAG_TRACE); + set_special (SPCFLAG_DOTRACE); + } +} + +void fill_prefetch_030_ntx (void) { uaecptr pc = m68k_getpc (); uaecptr pc2 = pc; @@ -8272,7 +8274,7 @@ void fill_prefetch_030 (void) regs.irc = get_word_030_prefetch(0); } -void fill_prefetch_020 (void) +void fill_prefetch_020_ntx(void) { uaecptr pc = m68k_getpc (); uaecptr pc2 = pc; @@ -8308,6 +8310,29 @@ void fill_prefetch_020 (void) regs.irc = get_word_020_prefetch (0); } +// Not exactly right, requires logic analyzer checks. +void continue_ce020_prefetch(void) +{ + fill_prefetch_020_ntx(); +} +void continue_020_prefetch(void) +{ + fill_prefetch_020_ntx(); +} + +void fill_prefetch_020(void) +{ + fill_prefetch_020_ntx(); + check_t0_trace(); +} + +void fill_prefetch_030(void) +{ + fill_prefetch_030_ntx(); + check_t0_trace(); +} + + void fill_prefetch (void) { regs.pipeline_pos = 0; -- 2.47.3