From 23add429c5e6b8e0402c5e0774df2c78252f9cff Mon Sep 17 00:00:00 2001 From: Toni Wilen Date: Mon, 2 Dec 2019 18:24:53 +0200 Subject: [PATCH] Cputest JMP and JSR bus error special case supported. "Stand-alone" trace exception supported (NOP before bus error or ILLEGAL) --- cputest.cpp | 53 +++++++++++++++++++++++++++++++++++++++++--------- cputest/main.c | 43 ++++++++++++++++++++++++++++------------ gencpu.cpp | 4 ++++ newcpu.cpp | 10 ++++++++-- 4 files changed, 87 insertions(+), 23 deletions(-) diff --git a/cputest.cpp b/cputest.cpp index b5e9fb0c..54c96c56 100644 --- a/cputest.cpp +++ b/cputest.cpp @@ -121,6 +121,8 @@ static int test_exception_3_fc; static int test_exception_3_size; static int test_exception_3_di; static int test_exception_opcode; +static uae_u32 trace_store_pc; +static uae_u16 trace_store_sr; static uae_u8 imm8_cnt; static uae_u16 imm16_cnt; @@ -924,6 +926,8 @@ void exception2_fetch(uae_u32 opcode, uaecptr addr) if (generates_group1_exception(regs.ir)) { test_exception_3_fc |= 8; // set N/I } + if (opcode & 0x10000) + test_exception_3_fc |= 8; } doexcstack(); @@ -943,6 +947,8 @@ void exception2_read(uae_u32 opcode, uaecptr addr, int size, int fc) if (generates_group1_exception(regs.ir)) { test_exception_3_fc |= 8; // set N/I } + if (opcode & 0x10000) + test_exception_3_fc |= 8; test_exception_opcode = regs.ir; } @@ -964,6 +970,8 @@ void exception2_write(uae_u32 opcode, uaecptr addr, int size, uae_u32 val, int f if (generates_group1_exception(regs.ir)) { test_exception_3_fc |= 8; // set N/I } + if (opcode & 0x10000) + test_exception_3_fc |= 8; test_exception_opcode = regs.ir; } @@ -2426,6 +2434,7 @@ static void execute_ins(uae_u16 opc, uaecptr endpc, uaecptr targetpc, struct ins // execute instruction SPCFLAG_TRACE = 0; SPCFLAG_DOTRACE = 0; + trace_store_pc = 0xffffffff; mmufixup[0].reg = -1; mmufixup[1].reg = -1; @@ -2489,32 +2498,44 @@ static void execute_ins(uae_u16 opc, uaecptr endpc, uaecptr targetpc, struct ins Exception(8); } - // Trace is only added as an exception if there was no other exceptions - // Trace stacked with other exception is handled later - if (SPCFLAG_DOTRACE && !test_exception) { - Exception(9); - } - // Amiga Chip ram does not support TAS or MOVE16 if ((dp->mnemo == i_TAS || dp->mnemo == i_MOVE16) && low_memory_accessed) { test_exception = -1; break; } - if (regs.pc == endpc || regs.pc == targetpc) + if (regs.pc == endpc || regs.pc == targetpc) { + // Trace is only added as an exception if there was no other exceptions + // Trace stacked with other exception is handled later + if (SPCFLAG_DOTRACE && !test_exception) { + Exception(9); + } break; + } - if (test_exception || SPCFLAG_DOTRACE) + if (test_exception) break; if (!valid_address(regs.pc, 2, 0)) break; - if (regs.pc + 2 == targetpc) { + if (targetpc != 0xffffffff && regs.pc + 2 == targetpc) { + // trace after jumping to branch target + // and opcode was NOP + if (SPCFLAG_DOTRACE) { + trace_store_pc = regs.pc; + trace_store_sr = regs.sr; + SPCFLAG_DOTRACE = 0; + } opc = regs.ir; continue; } + if (SPCFLAG_DOTRACE) { + wprintf(_T("Trace not supported in loop mode\n")); + abort(); + } + if (cpu_lvl < 2) { opc = get_word_test_prefetch(2); } else { @@ -2617,6 +2638,12 @@ static uae_u8 *save_exception(uae_u8 *p, struct instr *dp) uae_u8 *op = p; p++; *p++ = test_exception_extra; + // Separate, non-stacked Trace + if (test_exception_extra & 0x80) { + *p++ = trace_store_sr >> 8; + *p++ = trace_store_sr; + p = store_rel(p, 0, opcode_memory_start, trace_store_pc, 1); + } uae_u8 *sf = test_memory + test_memory_size + EXTRA_RESERVED_SPACE - exception_stack_frame_size; // parse exception and store fields that are unique // SR and PC was already saved with non-exception data @@ -3518,6 +3545,11 @@ static void test_mnemo(const TCHAR *path, const TCHAR *mnemo, const TCHAR *ovrfi MakeSR(); + if (SPCFLAG_DOTRACE && trace_store_pc != 0xffffffff) { + wprintf(_T("Trace and stored trace at the same time!\n")); + abort(); + } + // did we have trace also active? if (SPCFLAG_DOTRACE) { if (regs.t1 && (test_exception == 5 || test_exception == 6 || test_exception == 7 || (test_exception >= 32 && test_exception <= 47))) { @@ -3529,6 +3561,9 @@ static void test_mnemo(const TCHAR *path, const TCHAR *mnemo, const TCHAR *ovrfi regs.t0 = 0; regs.t1 = 0; } + if (trace_store_pc != 0xffffffff) { + test_exception_extra = 9 | 0x80; + } if (!skipped) { bool storeregs = true; diff --git a/cputest/main.c b/cputest/main.c index b5a0211d..a8d1f52c 100644 --- a/cputest/main.c +++ b/cputest/main.c @@ -93,7 +93,7 @@ static int low_memory_offset; static int high_memory_offset; static uae_u32 vbr[256]; -static int exceptioncount[256]; +static int exceptioncount[128]; static int supercnt; static char inst_name[16+1]; @@ -1110,26 +1110,44 @@ static uae_u8 *validate_exception(struct registers *regs, uae_u8 *p, int excnum, if (excdatalen != 0xff) { // check possible extra trace last_exception_extra = *p++; - // some other exception + trace - if (last_exception_extra == 9) { - exceptioncount[last_exception_extra]++; + if ((last_exception_extra & 0x7f) == 9) { + exceptioncount[last_exception_extra & 0x7f]++; + uae_u32 ret = (regs->tracedata[1] << 16) | regs->tracedata[2]; + uae_u16 sr = regs->tracedata[0]; if (regs->tracecnt == 0) { - sprintf(outbp, "Expected trace exception but got none\n", regs->tracecnt); + sprintf(outbp, "Expected trace exception but got none\n"); outbp += strlen(outbp); errors = 1; *experr = 1; - } else { - uae_u16 sr = regs->tracedata[0]; + } else if (!(last_exception_extra & 0x80)) { + // Trace stacked with group 2 exception if (!(sr & 0x2000) || (sr | 0x2000 | 0xc000) != (regs->sr | 0x2000 | 0xc000)) { - sprintf(outbp, "Trace exception stack frame SR mismatch: %04x != %04x\n", sr, regs->sr); + sprintf(outbp, "Trace (%d stacked) SR mismatch: %04x != %04x\n", excnum, sr, regs->sr); outbp += strlen(outbp); errors = 1; *experr = 1; } - uae_u32 ret = (regs->tracedata[1] << 16) | regs->tracedata[2]; uae_u32 retv = exceptiontableinuse + (excnum - 2) * 2; if (ret != retv) { - sprintf(outbp, "Trace exception stacked PC mismatch: %08lx != %08lx (%ld)\n", ret, retv, excnum); + sprintf(outbp, "Trace (%d stacked) PC mismatch: %08lx != %08lx (%ld)\n", excnum, ret, retv); + outbp += strlen(outbp); + errors = 1; + *experr = 1; + } + } else { + // Standalone Trace + uae_u16 vsr = (p[0] << 8) | (p[1]); + p += 2; + v = opcode_memory_addr; + p = restore_rel_ordered(p, &v); + if (vsr != sr) { + sprintf(outbp, "Trace (non-stacked) SR mismatch: %04x != %04x\n", sr, vsr); + outbp += strlen(outbp); + errors = 1; + *experr = 1; + } + if (v != ret) { + sprintf(outbp, "Trace (non-stacked) PC mismatch: %08lx != %08lx\n", ret, v); outbp += strlen(outbp); errors = 1; *experr = 1; @@ -1827,7 +1845,8 @@ static void process_test(uae_u8 *p) } p = validate_test(p, ignore_errors, ignore_sr); - if (regs.sr & 0x2000) + + if (super) supercnt++; last_pc = last_registers.pc; @@ -2059,7 +2078,7 @@ static int test_mnemo(const char *path, const char *opcode) } printf("S=%ld", supercnt); - for (int i = 0; i < 256; i++) { + for (int i = 0; i < 128; i++) { if (exceptioncount[i]) { printf(" E%02d=%ld", i, exceptioncount[i]); } diff --git a/gencpu.cpp b/gencpu.cpp index e301630f..d9614805 100644 --- a/gencpu.cpp +++ b/gencpu.cpp @@ -5185,6 +5185,8 @@ static void gen_opcode (unsigned int opcode) int sp = (curi->smode == Ad16 || curi->smode == absw || curi->smode == absl || curi->smode == PC16 || curi->smode == Ad8r || curi->smode == PC8r) ? -1 : 0; irc2ir(); printf("\topcode = regs.ir;\n"); + if (sp < 0) + printf("\tif(regs.t1) opcode |= 0x10000;\n"); printf("\t%s (%d);\n", prefetch_word, 2); check_prefetch_bus_error(-2, sp); did_prefetch = 1; @@ -5221,6 +5223,8 @@ static void gen_opcode (unsigned int opcode) printf("\t%s (%d);\n", prefetch_word, 2); int sp = (curi->smode == Ad16 || curi->smode == absw || curi->smode == absl || curi->smode == PC16 || curi->smode == Ad8r || curi->smode == PC8r) ? -1 : 0; printf("\topcode = regs.ir;\n"); + if (sp < 0) + printf("\tif(regs.t1) opcode |= 0x10000;\n"); check_prefetch_bus_error(-2, sp); did_prefetch = 1; ir2irc = 0; diff --git a/newcpu.cpp b/newcpu.cpp index 65e486a2..5f9a32cc 100644 --- a/newcpu.cpp +++ b/newcpu.cpp @@ -6874,7 +6874,7 @@ void exception3_read(uae_u32 opcode, uaecptr addr, int size, int fc) ni = true; fc = -1; } - if (opcode & 0x100000) + if (opcode & 0x10000) ni = true; opcode = regs.ir; } @@ -6888,7 +6888,7 @@ void exception3_write(uae_u32 opcode, uaecptr addr, int size, uae_u32 val, int f ni = true; fc = -1; } - if (opcode & 0x100000) + if (opcode & 0x10000) ni = true; opcode = regs.ir; } @@ -6944,6 +6944,8 @@ void exception2_read(uae_u32 opcode, uaecptr addr, int size, int fc) { exception2_setup(addr, true, size, fc); last_op_for_exception_3 = opcode; + if (opcode & 0x10000) + last_notinstruction_for_exception_3 = true; Exception(2); } @@ -6951,6 +6953,8 @@ void exception2_write(uae_u32 opcode, uaecptr addr, int size, uae_u32 val, int f { exception2_setup(addr, false, size, fc); last_op_for_exception_3 = opcode; + if (opcode & 0x10000) + last_notinstruction_for_exception_3 = true; regs.write_buffer = val; Exception(2); } @@ -6960,6 +6964,8 @@ void exception2_fetch(uae_u32 opcode, uaecptr addr) exception2_setup(addr, true, 1, 2); last_op_for_exception_3 = opcode; last_di_for_exception_3 = 0; + if (opcode & 0x10000) + last_notinstruction_for_exception_3 = true; Exception(2); } -- 2.47.3