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;
#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)
}
}
+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
}
uae_u32 memory_get_wordi(uaecptr addr)
{
- return get_word_test(addr);
+ return get_iword_test(addr);
}
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)
}
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;
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++;
}
if (opcodesize != 2) {
// not X: skip
+ // No need to generate multiple identical tests
return -2;
}
*fpuregused = (v >> 10) & 7;
} else {
put_word_test(pc, imm16_cnt++);
if (imm16_cnt == 0)
- *isconstant = 0;
+ *isconstant = 0;
else
*isconstant = -1;
}
}
case imm2:
{
+ if (dp->mnemo == i_FBcc || dp->mnemo == i_FTRAPcc) {
+ break;
+ }
// long immediate
uae_u32 v = rand32();
if ((imm32_cnt & 63) == 0) {
break;
}
}
+end:
*opcodep = opcode;
return pc - old_pc;
}
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) {
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)
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;
}
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("");
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)
{
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];
regs.usp = regs.regs[15];
regs.isp = super_stack_memory - 0x80;
- if (opc == 0xf228)
+ if (opc == 0xf27c)
printf("");
if (subtest_count >= 700)
printf("");
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)
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
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)
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++) {
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;
}
}
}
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) {
; ***********
; 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
; FPU illegal or unimplemented instructions
[test=IllgFPU]
-enabled=0
+enabled=1
verbose=1
cpu=68020-68060
fpu=68882
#include <dirent.h>
#endif
-#define DONTSTOPONERROR 0
-
typedef unsigned int uae_u32;
typedef int uae_s32;
typedef unsigned short uae_u16;
uae_u16 fpeaset;
};
+static short continue_on_error;
static struct registers test_regs;
static struct registers last_registers;
static struct registers regs;
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];
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];
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;
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;
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;
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;
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;
for (;;) {
-#ifndef M68K
- outbp = outbuffer2;
-#endif
-
regs.endpc = endpc;
regs.pc = startpc;
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);
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;
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;
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");
exitcnt = -1;
cyclecounter_addr = 0xffffffff;
cycles_range = 2;
+ outbuffer_size = DEFAULT_OUTBUFFER_SIZE;
for (int i = 1; i < argc; i++) {
char *s = argv[i];
}
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")) {
}
} else if (!_stricmp(s, "-uae")) {
uaemode = 1;
+ } else if (!_stricmp(s, "-outbuffer")) {
+ if (i + 1 < argc) {
+ i++;
+ outbuffer_size = atoi(argv[i]);
+ }
}
+
}
#ifdef M68K
}
#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, '/');
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)
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 \
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.