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;
if (generates_group1_exception(regs.ir)) {
test_exception_3_fc |= 8; // set N/I
}
+ if (opcode & 0x10000)
+ test_exception_3_fc |= 8;
}
doexcstack();
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;
}
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;
}
// execute instruction
SPCFLAG_TRACE = 0;
SPCFLAG_DOTRACE = 0;
+ trace_store_pc = 0xffffffff;
mmufixup[0].reg = -1;
mmufixup[1].reg = -1;
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 {
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
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))) {
regs.t0 = 0;
regs.t1 = 0;
}
+ if (trace_store_pc != 0xffffffff) {
+ test_exception_extra = 9 | 0x80;
+ }
if (!skipped) {
bool storeregs = true;
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];
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;
}
p = validate_test(p, ignore_errors, ignore_sr);
- if (regs.sr & 0x2000)
+
+ if (super)
supercnt++;
last_pc = last_registers.pc;
}
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]);
}
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;
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;
ni = true;
fc = -1;
}
- if (opcode & 0x100000)
+ if (opcode & 0x10000)
ni = true;
opcode = regs.ir;
}
ni = true;
fc = -1;
}
- if (opcode & 0x100000)
+ if (opcode & 0x10000)
ni = true;
opcode = regs.ir;
}
{
exception2_setup(addr, true, size, fc);
last_op_for_exception_3 = opcode;
+ if (opcode & 0x10000)
+ last_notinstruction_for_exception_3 = true;
Exception(2);
}
{
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);
}
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);
}