]> git.unchartedbackwaters.co.uk Git - francis/winuae.git/commitdiff
CPU tester updates, mainly FPU related.
authorToni Wilen <twilen@winuae.net>
Sun, 19 Apr 2020 15:19:21 +0000 (18:19 +0300)
committerToni Wilen <twilen@winuae.net>
Sun, 19 Apr 2020 15:19:21 +0000 (18:19 +0300)
cputest.cpp
cputest/cputestgen.ini
cputest/main.c
cputest/makefile
cputest/readme.txt

index 09452ebfc6ffcec750f4e9f249abbc0df5518db7..d045774d41ae125cbd1f6b44794afc1d5afb656f 100644 (file)
@@ -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) {
index bc80d780ea57abcb9a11d2f5481da7146239d4f7..d3bc4aea23d45ebe8c8e6e7480868091a58a5af3 100644 (file)
@@ -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
index 34308bce853bff1fcb5fda7040e01cf3673234dc..848dc371634a9a3e86a406a7a2436a0bda6d5c7f 100644 (file)
@@ -16,8 +16,6 @@
 #include <dirent.h>
 #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, &regs, 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 <mnemonic> = test all, starting from <mnemonic>\n");
                printf("all <mnemonic> -next = test all, starting after <mnemonic>\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)
index db65f34acb6b6980731919d413146e011ad35e98..7f2fc87c0241578aeffbc1396ed38aff289c5007 100644 (file)
@@ -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 \
index 18a4c3949f9d8d6857e69a3f41415baf2a8d5f80..47c1058765a72d0ee74e6b29c0c8adf7da59a160 100644 (file)
@@ -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.