From 000549dcf78c711df888284fb08fa5232dd36222 Mon Sep 17 00:00:00 2001 From: Toni Wilen Date: Sun, 19 Apr 2020 18:19:21 +0300 Subject: [PATCH] CPU tester updates, mainly FPU related. --- cputest.cpp | 209 ++++++++++++++++++++++++++++++++--------- cputest/cputestgen.ini | 22 +++-- cputest/main.c | 152 +++++++++++++++++++++--------- cputest/makefile | 2 +- cputest/readme.txt | 5 + 5 files changed, 296 insertions(+), 94 deletions(-) diff --git a/cputest.cpp b/cputest.cpp index 09452ebf..d045774d 100644 --- a/cputest.cpp +++ b/cputest.cpp @@ -130,6 +130,7 @@ static uae_u32 imm32_cnt; static uae_u32 immabsw_cnt; static uae_u32 immabsl_cnt; static uae_u32 specials_cnt; +static uae_u32 immfpu_cnt; static uae_u32 addressing_mask; static int opcodecnt; static int cpu_stopped; @@ -165,6 +166,11 @@ static int noaccesshistory = 0; #define MAX_ACCESSHIST 16000 static struct accesshistory ahist[MAX_ACCESSHIST]; +void cputester_fault(void) +{ + test_exception = -1; +} + static int is_superstack_use_required(void) { switch (testing_active_opcode) @@ -374,6 +380,27 @@ static uae_u16 get_iword_test(uaecptr addr) } } +uae_u32 get_ilong_test(uaecptr addr) +{ + uae_u32 v; + check_bus_error(addr, 0, regs.s ? 6 : 2); + if (addr & 1) { + uae_u8 v0 = get_ibyte_test(addr + 0); + uae_u16 v1 = get_iword_test(addr + 1); + uae_u8 v3 = get_ibyte_test(addr + 3); + v = (v0 << 24) | (v1 << 8) | (v3 << 0); + } else if (addr & 2) { + uae_u16 v0 = get_iword_test(addr + 0); + uae_u16 v1 = get_iword_test(addr + 2); + v = (v0 << 16) | (v1 << 0); + } else { + uae_u8 *p = get_addr(addr, 4, 1); + v = (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | (p[3]); + add_memory_cycles(2); + } + return v; +} + uae_u16 get_word_test_prefetch(int o) { // no real prefetch @@ -656,7 +683,7 @@ uae_u32 memory_get_word(uaecptr addr) } uae_u32 memory_get_wordi(uaecptr addr) { - return get_word_test(addr); + return get_iword_test(addr); } uae_u32 memory_get_long(uaecptr addr) { @@ -664,7 +691,7 @@ uae_u32 memory_get_long(uaecptr addr) } uae_u32 memory_get_longi(uaecptr addr) { - return get_long_test(addr); + return get_ilong_test(addr); } void memory_put_long(uaecptr addr, uae_u32 v) @@ -2462,7 +2489,9 @@ static int create_ea_random(uae_u16 *opcodep, uaecptr pc, int mode, int reg, str } case imm1: { - // word immediate + if (dp->mnemo == i_FBcc || dp->mnemo == i_FTRAPcc || dp->mnemo == i_FScc || dp->mnemo == i_FDBcc) { + break; + } if (fpuopcode >= 0) { int extra = 0; uae_u16 v = 0; @@ -2479,15 +2508,24 @@ static int create_ea_random(uae_u16 *opcodep, uaecptr pc, int mode, int reg, str if (imm16_cnt < 0x400) *isconstant = -1; } else if (opcodesize == 8) { - // FMOVEM/FMOVE to/from control registers + // FMOVEM/FMOVE to/from (control) registers v |= 0x8000; - v |= (imm16_cnt & 15) << 11; - v |= rand16() & 0x07ff; + v |= (imm16_cnt & 1) ? 0x2000 : 0x0000; // DR + // keep zero bits zero because at least 68040 can hang if wrong bits are set + // (at least set bit 10 causes hang if Control registers FMOVEM) + if (imm16_cnt & 2) { + // Control registers + int list = (imm16_cnt >> 2) & 7; + v |= list << 10; // REGISTER LIST + } else { + // FPU registers + v |= 0x4000; + uae_u16 mode = (imm16_cnt >> 3) & 3; // MODE + v |= mode << 11; + v |= rand8(); + } imm16_cnt++; - if (imm16_cnt >= 32) - *isconstant = 0; - else - *isconstant = -1; + *isconstant = 128; } else { v |= fpuopcode; imm16_cnt++; @@ -2513,6 +2551,7 @@ static int create_ea_random(uae_u16 *opcodep, uaecptr pc, int mode, int reg, str } if (opcodesize != 2) { // not X: skip + // No need to generate multiple identical tests return -2; } *fpuregused = (v >> 10) & 7; @@ -2605,7 +2644,7 @@ static int create_ea_random(uae_u16 *opcodep, uaecptr pc, int mode, int reg, str } else { put_word_test(pc, imm16_cnt++); if (imm16_cnt == 0) - *isconstant = 0; + *isconstant = 0; else *isconstant = -1; } @@ -2626,6 +2665,9 @@ static int create_ea_random(uae_u16 *opcodep, uaecptr pc, int mode, int reg, str } case imm2: { + if (dp->mnemo == i_FBcc || dp->mnemo == i_FTRAPcc) { + break; + } // long immediate uae_u32 v = rand32(); if ((imm32_cnt & 63) == 0) { @@ -2643,6 +2685,7 @@ static int create_ea_random(uae_u16 *opcodep, uaecptr pc, int mode, int reg, str break; } } +end: *opcodep = opcode; return pc - old_pc; } @@ -2925,15 +2968,56 @@ static int generate_fpu_memory_read(uae_u16 opcode, uaecptr pc, struct instr *dp static int imm_special; -static int handle_specials_preea(uae_u16 opcode, uaecptr pc, struct instr *dp) +static int handle_specials_preea(uae_u16 opcode, uaecptr pc, struct instr *dp, int *isconstant) { + int off = 0; + int f = 0; if (dp->mnemo == i_FTRAPcc) { - uae_u16 v = rand16(); - v &= ~7; - v |= imm_special; + uae_u16 v = imm_special & 63; + int mode = opcode & 7; put_word_test(pc, v); imm_special++; - return 2; + off += 2; + pc += 2; + if (mode == 2) { + f = 1; + } else if (mode == 3) { + f = 2; + } else { + f = -1; + } + *isconstant = 64; + } + if (dp->mnemo == i_FScc || dp->mnemo == i_FDBcc) { + uae_u16 v = immfpu_cnt & 63; + immfpu_cnt++; + *isconstant = 64; + put_word_test(pc, v); + pc += 2; + off += 2; + if (dp->mnemo == i_FDBcc) { + f = 1; + } + } else if (dp->mnemo == i_FBcc) { + opcode |= immfpu_cnt & 63; + immfpu_cnt++; + *isconstant = 64; + f = (opcode & 0x40) ? 2 : 1; + } + if (f) { + uae_s16 v; + for (;;) { + v = rand16() & ~1; + if (v > 128 || v < -128) + break; + } + if (f == 2) { + put_long_test(pc, v); + off += 4; + } else if (f == 1) { + put_word_test(pc, v); + off += 2; + } } if (dp->mnemo == i_MOVE16) { if (opcode & 0x20) { @@ -2941,10 +3025,10 @@ static int handle_specials_preea(uae_u16 opcode, uaecptr pc, struct instr *dp) v |= imm_special << 12; put_word_test(pc, v); imm_special++; - return 2; + off = 2; } } - return 0; + return off; } static int handle_specials_branch(uae_u16 opcode, uaecptr pc, struct instr *dp, int *isconstant) @@ -2955,12 +3039,6 @@ static int handle_specials_branch(uae_u16 opcode, uaecptr pc, struct instr *dp, return 0; } return -2; - } else if (dp->mnemo == i_FDBcc) { - // FDBcc jump offset - uae_u16 v = rand16(); - put_word_test(pc, v); - *isconstant = 16; - return 2; } return 0; } @@ -3284,7 +3362,7 @@ static void execute_ins(uaecptr endpc, uaecptr targetpc, struct instr *dp) uae_u16 opw1 = (opcode_memory[2] << 8) | (opcode_memory[3] << 0); uae_u16 opw2 = (opcode_memory[4] << 8) | (opcode_memory[5] << 0); if (opc == 0xf200 - && opw1 == 0x0019 + && opw1 == 0x6c12 //&& opw2 == 0x4afc ) printf(""); @@ -3681,6 +3759,19 @@ static int isfpp(int mnemo) return 0; } +static void outbytes(const TCHAR *s, uaecptr addr) +{ +#if 0 + wprintf(_T(" %s=%08x="), s, addr); + for (int i = 0; i < 8; i++) { + uae_u8 c = get_byte_test(addr + i); + if (i > 0) + wprintf(_T(".")); + wprintf(_T("%02x"), c); + } +#endif +} + static void generate_target_registers(uae_u32 target_address, uae_u32 *out) { @@ -4020,6 +4111,7 @@ static void test_mnemo(const TCHAR *path, const TCHAR *mnemo, const TCHAR *ovrfi immabsl_cnt = 0; immabsw_cnt = 0; imm_special = 0; + immfpu_cnt = 0; target_ea[0] = target_ea_bak[0]; target_ea[1] = target_ea_bak[1]; @@ -4088,7 +4180,7 @@ static void test_mnemo(const TCHAR *path, const TCHAR *mnemo, const TCHAR *ovrfi regs.usp = regs.regs[15]; regs.isp = super_stack_memory - 0x80; - if (opc == 0xf228) + if (opc == 0xf27c) printf(""); if (subtest_count >= 700) printf(""); @@ -4120,14 +4212,18 @@ static void test_mnemo(const TCHAR *path, const TCHAR *mnemo, const TCHAR *ovrfi if (dp->mnemo != i_ILLG && fpuopcode != FPUOPP_ILLEGAL) { - pc += handle_specials_preea(opc, pc, dp); + pc += handle_specials_preea(opc, pc, dp, &isconstant_src); uae_u32 srcea = 0xffffffff; uae_u32 dstea = 0xffffffff; // create source addressing mode if (dp->suse) { + int isconstant_tmp = isconstant_src; int o = create_ea(&opc, pc, dp->smode, dp->sreg, dp, &isconstant_src, 0, fpuopcode, opcodesize, &srcea, &srcregused, &srcfpuregused); + if (isconstant_src < isconstant_tmp && isconstant_src > 0) { + isconstant_src = isconstant_tmp; + } if (o < 0) { memcpy(opcode_memory, oldcodebytes, sizeof(oldcodebytes)); if (o == -1) @@ -4328,6 +4424,12 @@ static void test_mnemo(const TCHAR *path, const TCHAR *mnemo, const TCHAR *ovrfi if (verbose) { my_trim(out); wprintf(_T("%08u %s"), subtest_count, out); + if (srcaddr != 0xffffffff) { + outbytes(_T("S"), srcaddr); + } + if (dstaddr != 0xffffffff && srcaddr != dstaddr) { + outbytes(_T("D"), dstaddr); + } } // disassembler may set this @@ -4509,10 +4611,26 @@ static void test_mnemo(const TCHAR *path, const TCHAR *mnemo, const TCHAR *ovrfi for (;;) { uae_u16 sr_mask = 0; - int maxflag = fpumode ? 256 : 32; - // if cc-instruction: always do full test - if (feature_flag_mode > 1 || (feature_flag_mode == 1 && (dp->mnemo == i_ILLG || fpuopcode == FPUOPP_ILLEGAL || (!dp->ccuse && !fpumode)))) { - maxflag = fpumode ? 256 / 8 : 2; + int maxflag; + int flagmode = 0; + if (fpumode) { + if (fpuopcode == FPUOPP_ILLEGAL) { + // Illegal FPU instruction: all on/all off only (*2) + maxflag = 2; + } else if (dp->mnemo == i_FDBcc || dp->mnemo == i_FScc || dp->mnemo == i_FTRAPcc || dp->mnemo == i_FBcc) { + // FXXcc-instruction: FPU condition codes (*16) + maxflag = 16; + flagmode = 1; + } else { + // Other FPU instructions: FPU rounding and precision (*16) + maxflag = 16; + } + } else { + maxflag = 32; // all flag combinations (*32) + if (feature_flag_mode > 1 || (feature_flag_mode == 1 && (dp->mnemo == i_ILLG || !dp->ccuse))) { + // if not cc instruction or illegal or forced: all on/all off (*2) + maxflag = 2; + } } if (extraccr & 1) @@ -4530,7 +4648,7 @@ static void test_mnemo(const TCHAR *path, const TCHAR *mnemo, const TCHAR *ovrfi if (extraccr) { *dst++ = (uae_u8)extraccr; } - *dst++ = (uae_u8)maxflag; + *dst++ = (uae_u8)(maxflag | (fpumode ? 0x80 : 0x00) | (flagmode ? 0x40 : 0x00)); // Test every CPU CCR or FPU SR/rounding/precision combination for (int ccr = 0; ccr < maxflag; ccr++) { @@ -4604,20 +4722,27 @@ static void test_mnemo(const TCHAR *path, const TCHAR *mnemo, const TCHAR *ovrfi regs.fp[i].fpx = cur_fpuregisters[i]; } regs.fpiar = regs.pc; - // condition codes - if (maxflag > 32) { - fpp_set_fpsr((ccr & 15) << 24); - // precision and rounding - fpp_set_fpcr((ccr >> 4) << 4); + uae_u32 fpsr = 0, fpcr = 0; + if (maxflag == 16) { + if (flagmode) { + fpsr = (ccr & 15) << 24; + } else { + fpcr = (ccr & 15) << 4; + } } else { - fpp_set_fpsr(((ccr & 1) ? 15 : 0) << 24); - // precision and rounding - fpp_set_fpcr((ccr >> 1) << 4); + // 2 + fpsr = ((ccr & 1) ? 15 : 0) << 24; + fpcr = ((ccr & 1) ? 15 : 0) << 4; } + // condition codes + fpp_set_fpsr(fpsr); + // precision and rounding + fpp_set_fpcr(fpcr); + } // all CCR combinations or only all ones/all zeros? if (maxflag >= 32) { - regs.sr = ccr | sr_mask; + regs.sr = (ccr & 0xff) | sr_mask; } else { regs.sr = ((ccr & 1) ? 31 : 0) | sr_mask; } @@ -4849,7 +4974,7 @@ static void test_mnemo(const TCHAR *path, const TCHAR *mnemo, const TCHAR *ovrfi } } if (regs.fpiar != last_fpiar) { - dst = store_rel(dst, CT_FPIAR, last_fpiar, regs.fpiar, 0); + dst = store_reg(dst, CT_FPIAR, last_fpiar, regs.fpiar, -1); last_fpiar = regs.fpiar; } if (regs.fpsr != last_fpsr) { diff --git a/cputest/cputestgen.ini b/cputest/cputestgen.ini index bc80d780..d3bc4aea 100644 --- a/cputest/cputestgen.ini +++ b/cputest/cputestgen.ini @@ -374,17 +374,23 @@ feature_exception_vectors=0x000123 ; *********** ; basic test -; no arithmetic exceptions, F-line, unsupported instructions or datatypes, denormals or unnormals. +; no arithmetic exceptions, unsupported instructions or datatypes, denormals or unnormals. [test=BasicFPU] -enabled=1 +enabled=0 verbose=1 cpu=68020-68060 fpu=68882 -feature_flags_mode=2 -exceptions=-48,-49,-50,-51,-52,-53,-54,-11 -mode=fneg.b -mode=fbcc,ftrapcc,fscc,fdbcc -mode=fmove,fsmove,fdmove,fint,fintrz,fneg,fsneg,fdneg,fabs,fsabs,fdabs,fdiv,fsdiv,fddiv,fadd,fsadd,fdadd,fmul,fsmul,fdmul,fsgldiv,fsglmul,fsub,fssub,fdsub,fcmp,ftst +exceptions=-48,-49,-50,-51,-52,-53,-54 +min_opcode_test_rounds=5000 +mode=fmove,fsmove,fdmove,fint,fintrz,fneg,fsneg,fdneg,fabs,fsabs,fdabs,fdiv,fsdiv,fddiv,fadd,fsadd,fdadd,fmul,fsmul,fdmul,fsgldiv,fsglmul,fsub,fssub,fdsub,fcmp,ftst,fsqrt + +; non-arithmetic instructions (FMOVEM also includes FMOVE to/from control register) +[test=intFPU] +enabled=0 +verbose=1 +cpu=68020-68060 +fpu=68882 +mode=fmovecr,fmovem,fdbcc,fbcc,ftrapcc,fscc ; packed datatype ; no exceptions @@ -399,7 +405,7 @@ mode=fall ; FPU illegal or unimplemented instructions [test=IllgFPU] -enabled=0 +enabled=1 verbose=1 cpu=68020-68060 fpu=68882 diff --git a/cputest/main.c b/cputest/main.c index 34308bce..848dc371 100644 --- a/cputest/main.c +++ b/cputest/main.c @@ -16,8 +16,6 @@ #include #endif -#define DONTSTOPONERROR 0 - typedef unsigned int uae_u32; typedef int uae_s32; typedef unsigned short uae_u16; @@ -60,6 +58,7 @@ struct registers uae_u16 fpeaset; }; +static short continue_on_error; static struct registers test_regs; static struct registers last_registers; static struct registers regs; @@ -109,13 +108,10 @@ static int supercnt; static uae_u32 startpc, endpc; static char inst_name[16+1]; -#ifndef M68K -static char outbuffer[40000]; -static char outbuffer2[40000]; -#else -static char outbuffer[4000]; -static char outbuffer2[4000]; -#endif +#define DEFAULT_OUTBUFFER_SIZE 20000 +static int outbuffer_size; +static char *outbuffer; +static char *outbuffer2; static char tmpbuffer[1024]; static char path[256]; @@ -148,8 +144,8 @@ static short interrupt_count; static uae_u16 main_intena; #endif -#define SIZE_STORED_ADDRESS_OFFSET 8 -#define SIZE_STORED_ADDRESS 16 +#define SIZE_STORED_ADDRESS_OFFSET 6 +#define SIZE_STORED_ADDRESS 20 static uae_u8 srcaddr[SIZE_STORED_ADDRESS]; static uae_u8 dstaddr[SIZE_STORED_ADDRESS]; static uae_u8 branchtarget[SIZE_STORED_ADDRESS]; @@ -2083,7 +2079,11 @@ static uae_u8 *validate_test(uae_u8 *p, short ignore_errors, short ignore_sr) p = restore_value(p, &val, &size); if (val != test_regs.regs[mode] && !ignore_errors && !skipregchange) { if (dooutput) { - sprintf(outbp, "%c%d: expected %08x but got %08x\n", mode < CT_AREG ? 'D' : 'A', mode & 7, val, test_regs.regs[mode]); + if (regs.regs[mode] == test_regs.regs[mode]) { + sprintf(outbp, "%c%d: expected %08x but register was not modified\n", mode < CT_AREG ? 'D' : 'A', mode & 7, val); + } else { + sprintf(outbp, "%c%d: expected %08x but got %08x\n", mode < CT_AREG ? 'D' : 'A', mode & 7, val, test_regs.regs[mode]); + } outbp += strlen(outbp); } errflag |= 1 << 0; @@ -2095,9 +2095,16 @@ static uae_u8 *validate_test(uae_u8 *p, short ignore_errors, short ignore_sr) p = restore_fpvalue(p, &val); if (memcmp(&val, &test_regs.fpuregs[mode], sizeof(struct fpureg)) && !ignore_errors) { if (dooutput) { - sprintf(outbp, "FP%d: expected %04x-%08x%08x but got %04x-%08x%08x\n", mode, - val.exp, val.m[0], val.m[1], - test_regs.fpuregs[mode].exp, test_regs.fpuregs[mode].m[0], test_regs.fpuregs[mode].m[1]); + if (regs.fpuregs[mode].m[0] == test_regs.fpuregs[mode].m[0] && + regs.fpuregs[mode].m[1] == test_regs.fpuregs[mode].m[1] && + regs.fpuregs[mode].exp == test_regs.fpuregs[mode].exp) { + sprintf(outbp, "FP%d: expected %04x-%08x%08x but register was not modified\n", mode, + val.exp, val.m[0], val.m[1]); + } else { + sprintf(outbp, "FP%d: expected %04x-%08x%08x but got %04x-%08x%08x\n", mode, + val.exp, val.m[0], val.m[1], + test_regs.fpuregs[mode].exp, test_regs.fpuregs[mode].m[0], test_regs.fpuregs[mode].m[1]); + } outbp += strlen(outbp); } errflag |= 1 << 1; @@ -2164,7 +2171,11 @@ static uae_u8 *validate_test(uae_u8 *p, short ignore_errors, short ignore_sr) p = restore_value(p, &val, &size); if (val != test_regs.fpcr && !ignore_errors) { if (dooutput) { - sprintf(outbp, "FPCR: expected %08x -> %08x but got %08x\n", test_fpcr, val, test_regs.fpcr); + if (regs.fpcr == test_regs.fpcr) { + sprintf(outbp, "FPCR: expected %08x but register was not modified\n", val); + } else { + sprintf(outbp, "FPCR: expected %08x -> %08x but got %08x\n", test_fpcr, val, test_regs.fpcr); + } outbp += strlen(outbp); } errflag |= 1 << 3; @@ -2177,7 +2188,11 @@ static uae_u8 *validate_test(uae_u8 *p, short ignore_errors, short ignore_sr) p = restore_value(p, &val, &size); if (val != test_regs.fpsr && !ignore_errors) { if (dooutput) { - sprintf(outbp, "FPSR: expected %08x -> %08x but got %08x\n", test_fpsr, val, test_regs.fpsr); + if (regs.fpsr == test_regs.fpsr) { + sprintf(outbp, "FPSR: expected %08x but register was not modified\n", val); + } else { + sprintf(outbp, "FPSR: expected %08x -> %08x but got %08x\n", test_fpsr, val, test_regs.fpsr); + } outbp += strlen(outbp); } errflag |= 1 << 4; @@ -2186,10 +2201,15 @@ static uae_u8 *validate_test(uae_u8 *p, short ignore_errors, short ignore_sr) last_registers.fpsr = val; } else if (mode == CT_FPIAR) { uae_u32 val = last_registers.fpiar; - p = restore_rel(p, &val, 0); + int size; + p = restore_value(p, &val, &size); if (val != test_regs.fpiar && !ignore_errors) { if (dooutput) { - sprintf(outbp, "FPIAR: expected %08x but got %08x\n", val, test_regs.fpiar); + if (regs.fpiar == test_regs.fpiar) { + sprintf(outbp, "FPIAR: expected %08x but register was not modified\n", val); + } else { + sprintf(outbp, "FPIAR: expected %08x but got %08x\n", val, test_regs.fpiar); + } outbp += strlen(outbp); } errflag |= 1 << 5; @@ -2460,10 +2480,6 @@ static void process_test(uae_u8 *p) for (;;) { -#ifndef M68K - outbp = outbuffer2; -#endif - regs.endpc = endpc; regs.pc = startpc; @@ -2521,9 +2537,8 @@ static void process_test(uae_u8 *p) if (extraccr & 8) sr_mask |= 0x1000; // M - int maxccr = *p++; - if (!maxccr) - maxccr = 256; + uae_u8 ccrmode = *p++; + int maxccr = ccrmode & 0x3f; for (int ccr = 0; ccr < maxccr; ccr++) { opcodeend = (opcodeend >> 16) | (opcodeend << 16); @@ -2562,20 +2577,28 @@ static void process_test(uae_u8 *p) xmemcpy(&test_regs, ®s, sizeof(struct registers)); if (maxccr >= 32) { - test_regs.sr = ccr; + test_regs.sr = ccr & 0xff; } else { - test_regs.sr = (ccr ? 31 : 0); + test_regs.sr = (ccr & 1) ? 31 : 0; } test_regs.sr |= sr_mask | (interrupt_mask << 8); test_regs.expsr = test_regs.sr | 0x2000; test_sr = test_regs.sr; if (fpumode) { - if (maxccr > 32) { - test_regs.fpsr = (ccr & 15) << 24; - test_regs.fpcr = (ccr >> 4) << 4; - } else { + test_regs.fpcr = 0; + test_regs.fpsr = 0; + if (maxccr < 16) { + // all on/all off test_regs.fpsr = ((ccr & 1) ? 15 : 0) << 24; - test_regs.fpcr = (ccr >> 1) << 4; + test_regs.fpcr = ((ccr & 1) ? 15 : 0) << 4; + } else { + if (ccrmode & 0x40) { + // condition modes + test_regs.fpsr = (ccr & 15) << 24; + } else { + // precision and rounding + test_regs.fpcr = (ccr & 15) << 4; + } } test_fpsr = test_regs.fpsr; test_fpcr = test_regs.fpcr; @@ -2689,17 +2712,17 @@ static void process_test(uae_u8 *p) exit(0); } -#if DONTSTOPONERROR == 0 - if (quit || errors) - goto end; -#endif - } - - if (randomizetest) { - ; + if (quit || errors) { + if (continue_on_error) { + // always abort if buffer is getting too small + if (outbp - outbuffer >= outbuffer_size - 3000) + goto end; + } else { + goto end; + } + } } - if (*p == CT_END) { p++; break; @@ -3031,7 +3054,8 @@ int main(int argc, char *argv[]) printf("all = test all\n"); printf("all = test all, starting from \n"); printf("all -next = test all, starting after \n"); - printf("-continue = don't stop on error (all mode only)\n"); + printf("-continue = don't stop on error (continue to next test, all mode only)\n"); + printf("-nostop = don't stop on error (continue current instruction)\n"); printf("-ccrmask = ignore CCR bits that are not set.\n"); printf("-nodisasm = do not disassemble failed test.\n"); printf("-basicexc = do only basic checks when exception is 2 or 3.\n"); @@ -3057,6 +3081,7 @@ int main(int argc, char *argv[]) exitcnt = -1; cyclecounter_addr = 0xffffffff; cycles_range = 2; + outbuffer_size = DEFAULT_OUTBUFFER_SIZE; for (int i = 1; i < argc; i++) { char *s = argv[i]; @@ -3067,6 +3092,8 @@ int main(int argc, char *argv[]) } if (!_stricmp(s, "-continue")) { stop_on_error = 0; + } else if (!_stricmp(s, "-nostop")) { + continue_on_error = 1; } else if (!_stricmp(s, "-noundefined")) { check_undefined_sr = 0; } else if (!_stricmp(s, "-ccrmask")) { @@ -3127,7 +3154,13 @@ int main(int argc, char *argv[]) } } else if (!_stricmp(s, "-uae")) { uaemode = 1; + } else if (!_stricmp(s, "-outbuffer")) { + if (i + 1 < argc) { + i++; + outbuffer_size = atoi(argv[i]); + } } + } #ifdef M68K @@ -3148,6 +3181,16 @@ int main(int argc, char *argv[]) } #endif + if (outbuffer_size < 4000) { + outbuffer_size = 4000; + } + outbuffer = (char*)calloc(outbuffer_size, 1); + outbuffer2 = (char*)calloc(outbuffer_size, 1); + if (!outbuffer || !outbuffer2) { + printf("Out of memory when allocating output buffer.\n"); + return 0; + } + DIR *groupd = NULL; char *p = strchr(opcode, '/'); @@ -3276,6 +3319,29 @@ int main(int argc, char *argv[]) if (err && stop_on_error) break; + } else if (opcode[0] && opcode[strlen(opcode) - 1] == '*') { + DIR *d = opendir(path); + if (!d) { + printf("Couldn't list directory '%s'\n", path); + return 0; + } + for (;;) { + struct dirent *dr = readdir(d); + if (!dr) + break; + if (!strnicmp(dr->d_name, opcode, strlen(opcode) - 1)) { + int d = isdir(path, dr->d_name); + if (d) { + if (test_mnemo(dr->d_name)) { + if (stop_on_error) + break; + } + } + } + } + closedir(d); + + } else { if (test_mnemo(opcode)) { if (stop_on_error) diff --git a/cputest/makefile b/cputest/makefile index db65f34a..7f2fc87c 100644 --- a/cputest/makefile +++ b/cputest/makefile @@ -5,7 +5,7 @@ NOWTIME := "\"$(shell date "+%T")\"" CC=/opt/amiga/bin/m68k-amigaos-gcc AS=/opt/amiga/bin/m68k-amigaos-as -CFLAGS = -mcrt=nix13 -O2 -m68000 -fomit-frame-pointer -msmall-code -msoft-float -DREVDATE=$(NOWDATE) -DREVTIME=$(NOWTIME) -DAMIGA -DM68K +CFLAGS = -mcrt=nix13 -O2 -m68000 -fomit-frame-pointer -msoft-float -DREVDATE=$(NOWDATE) -DREVTIME=$(NOWTIME) -DAMIGA -DM68K LINK_CFLAGS = -mcrt=nix13 -lm -s OBJS = main.o asm040.o asm060.o amiga.o \ diff --git a/cputest/readme.txt b/cputest/readme.txt index 18a4c394..47c10587 100644 --- a/cputest/readme.txt +++ b/cputest/readme.txt @@ -131,6 +131,11 @@ If mismatch is detected, opcode word(s), instruction disassembly, registers befo Change log: +19.04.2020 + +- * = ignore rest of name, for example "cputest basic/neg*" will run NEG.B, NEG.W and NEG.L tests. +- FMOVECR, FMOVEM (includes FMOVE to/from control register), FDBcc, FBcc, FTRAPcc and FScc tests improved. + 11.04.2020 - Working FPU support. Not all tests work correctly yet. -- 2.47.3