From 2f7cf226de3e80b377a5d8310eac73e96a255a84 Mon Sep 17 00:00:00 2001 From: Toni Wilen Date: Sun, 22 Dec 2019 16:19:00 +0200 Subject: [PATCH] Experimental 68000 prefetch bus error emulation support: shift/rotate instructions, some RMW instructions. --- cputest.cpp | 104 ++++++++++++------ cputest/cputestgen.ini | 11 +- cputest/main.c | 26 +++-- gencpu.cpp | 240 +++++++++++++++++++++++++---------------- 4 files changed, 239 insertions(+), 142 deletions(-) diff --git a/cputest.cpp b/cputest.cpp index 1d84242e..0bfd73e4 100644 --- a/cputest.cpp +++ b/cputest.cpp @@ -289,13 +289,15 @@ static void check_bus_error(uaecptr addr, int write, int fc) return; if (addr >= safe_memory_start && addr < safe_memory_end) { cpu_bus_error_fake = -1; - if ((safe_memory_mode & 1) && !write) { - cpu_bus_error = 1; - cpu_bus_error_fake = 1; - } - if ((safe_memory_mode & 2) && write) { - cpu_bus_error = 2; - cpu_bus_error_fake = 2; + if ((safe_memory_mode & 4) && !write && (fc & 2)) { + cpu_bus_error |= 4; + cpu_bus_error_fake |= 1; + } else if ((safe_memory_mode & 1) && !write && !(fc & 2)) { + cpu_bus_error |= 1; + cpu_bus_error_fake |= 1; + } else if ((safe_memory_mode & 2) && write) { + cpu_bus_error |= 2; + cpu_bus_error_fake |= 2; } } } @@ -342,6 +344,8 @@ static void previoussame(uaecptr addr, int size) void put_byte_test(uaecptr addr, uae_u32 v) { + if (!testing_active && is_nowrite_address(addr, 1)) + return; check_bus_error(addr, 1, regs.s ? 5 : 1); uae_u8 *p = get_addr(addr, 1, 1); if (!out_of_test_space && !noaccesshistory && !cpu_bus_error_fake) { @@ -361,6 +365,8 @@ void put_byte_test(uaecptr addr, uae_u32 v) } void put_word_test(uaecptr addr, uae_u32 v) { + if (!testing_active && is_nowrite_address(addr, 1)) + return; check_bus_error(addr, 1, regs.s ? 5 : 1); if (addr & 1) { put_byte_test(addr + 0, v >> 8); @@ -386,6 +392,8 @@ void put_word_test(uaecptr addr, uae_u32 v) } void put_long_test(uaecptr addr, uae_u32 v) { + if (!testing_active && is_nowrite_address(addr, 1)) + return; check_bus_error(addr, 1, regs.s ? 5 : 1); if (addr & 1) { put_byte_test(addr + 0, v >> 24); @@ -915,7 +923,7 @@ void exception2_fetch(uae_u32 opcode, uaecptr addr) test_exception_3_di = 0; if (currprefs.cpu_model == 68000) { - if (generates_group1_exception(regs.ir)) { + if (generates_group1_exception(regs.ir) && !(opcode & 0x20000)) { test_exception_3_fc |= 8; // set N/I } if (opcode & 0x10000) @@ -1276,6 +1284,11 @@ static uae_u8 *store_mem_bytes(uae_u8 *dst, uaecptr start, int len, uae_u8 *old, wprintf(_T(" too long byte count!\n")); abort(); } + if (is_nowrite_address(start, 1) || is_nowrite_address(start + len - 1, 1)) { + wprintf(_T(" store_mem_bytes accessing safe memory area! (%08x - %08x)\n"), start, start + len - 1); + abort(); + } + uaecptr oldstart = start; uae_u8 offset = 0; // start @@ -1327,7 +1340,11 @@ static uae_u8 *store_mem_writes(uae_u8 *dst, int storealways) validate_addr(ah->addr, 1 << ah->size); uaecptr addr = ah->addr; addr &= addressing_mask; - if (addr < 0x8000) { + if (is_nowrite_address(addr, 1)) { + wprintf(_T("attempting to save safe memory address %08x!\n"), addr); + abort(); + } + if (addr < 0x8000) { *dst++ = CT_MEMWRITE | CT_ABSOLUTE_WORD; *dst++ = (addr >> 8) & 0xff; *dst++ = addr & 0xff; @@ -3173,6 +3190,11 @@ static void test_mnemo(const TCHAR *path, const TCHAR *mnemo, const TCHAR *ovrfi uaecptr pc = opcode_memory_start + 2; + + if (is_nowrite_address(pc, 1)) { + goto nextopcode; + } + if (target_opcode_address != 0xffffffff) { pc -= 2; int cnt = 0; @@ -3300,6 +3322,11 @@ static void test_mnemo(const TCHAR *path, const TCHAR *mnemo, const TCHAR *ovrfi pc += 4; } + // if instruction was long enough to hit safe area, decrease pc until we are back to normal area + while (is_nowrite_address(pc - 1, 1)) { + pc -= 2; + } + // end word, needed to detect if instruction finished normally when // running on real hardware. uae_u32 originalendopcode = 0x4afc4e71; @@ -3674,8 +3701,13 @@ static void test_mnemo(const TCHAR *path, const TCHAR *mnemo, const TCHAR *ovrfi // if only testing read bus errors, skip tests that generated only writes and vice-versa // skip also all tests don't generate any bus errors if ((cpu_bus_error == 0 && safe_memory_mode) || - (cpu_bus_error == 1 && !(safe_memory_mode & 1)) || - (cpu_bus_error == 2 && !(safe_memory_mode & 2))) { + ((cpu_bus_error & 4) && !(safe_memory_mode & 4)) || + ((cpu_bus_error & 1) && !(safe_memory_mode & 1)) || + ((cpu_bus_error & 2) && !(safe_memory_mode & 2))) { + skipped = 1; + } + // skip if feature_target_opcode_offset mode and non-prefetch bus error + if (target_opcode_address != 0xffffffff && (cpu_bus_error & 3)) { skipped = 1; } @@ -4208,6 +4240,30 @@ int __cdecl main(int argc, char *argv[]) feature_exception3_instruction = 0; ini_getval(ini, INISECTION, _T("feature_exception3_instruction"), &feature_exception3_instruction); + safe_memory_start = 0xffffffff; + if (ini_getval(ini, INISECTION, _T("feature_safe_memory_start"), &v)) + safe_memory_start = v; + safe_memory_end = 0xffffffff; + if (ini_getval(ini, INISECTION, _T("feature_safe_memory_size"), &v)) + safe_memory_end = safe_memory_start + v; + safe_memory_mode = 7; + if (ini_getstring(ini, INISECTION, _T("feature_safe_memory_mode"), &vs)) { + safe_memory_mode = 0; + if (_totupper(vs[0]) == 'R') + safe_memory_mode |= 1; + if (_totupper(vs[0]) == 'W') + safe_memory_mode |= 2; + if (_totupper(vs[0]) == 'P') + safe_memory_mode |= 4; + xfree(vs); + } + if (safe_memory_start == 0xffffffff || safe_memory_end == 0xffffffff) { + safe_memory_end = 0xffffffff; + safe_memory_start = 0xffffffff; + safe_memory_mode = 0; + } + + for (int i = 0; i < MAX_TARGET_EA; i++) { feature_target_ea[i][0] = 0xffffffff; feature_target_ea[i][1] = 0xffffffff; @@ -4226,10 +4282,12 @@ int __cdecl main(int argc, char *argv[]) *pp++ = 0; } TCHAR *endptr; + int radix = i == 2 ? 10 : 16; if (_tcslen(p) > 2 && p[0] == '0' && _totupper(p[1]) == 'X') { p += 2; + radix = 16; } - feature_target_ea[cnt][i] = _tcstol(p, &endptr, 16); + feature_target_ea[cnt][i] = _tcstol(p, &endptr, radix); if (feature_target_ea[cnt][i] & 1) { exp3cnt++; } @@ -4238,6 +4296,7 @@ int __cdecl main(int argc, char *argv[]) } if (i == 2) { target_ea_opcode_max = cnt; + safe_memory_mode = 7; } else if (i) { target_ea_dst_max = cnt; } else { @@ -4258,27 +4317,6 @@ int __cdecl main(int argc, char *argv[]) } } - safe_memory_start = 0xffffffff; - if (ini_getval(ini, INISECTION, _T("feature_safe_memory_start"), &v)) - safe_memory_start = v; - safe_memory_end = 0xffffffff; - if (ini_getval(ini, INISECTION, _T("feature_safe_memory_size"), &v)) - safe_memory_end = safe_memory_start + v; - safe_memory_mode = 3; - if (ini_getstring(ini, INISECTION, _T("feature_safe_memory_mode"), &vs)) { - safe_memory_mode = 0; - if (_totupper(vs[0]) == 'R') - safe_memory_mode |= 1; - if (_totupper(vs[0]) == 'W') - safe_memory_mode |= 2; - xfree(vs); - } - if (safe_memory_start == 0xffffffff || safe_memory_end == 0xffffffff) { - safe_memory_end = 0xffffffff; - safe_memory_start = 0xffffffff; - safe_memory_mode = 0; - } - feature_sr_mask = 0; ini_getval(ini, INISECTION, _T("feature_sr_mask"), &feature_sr_mask); feature_min_interrupt_mask = 0; diff --git a/cputest/cputestgen.ini b/cputest/cputestgen.ini index dfe8810a..0353df5c 100644 --- a/cputest/cputestgen.ini +++ b/cputest/cputestgen.ini @@ -69,11 +69,14 @@ feature_target_src_ea= ; Memory region that generates bus error (both read and write). ; Must be inside any test memory region. ; Can be used to verify bus errors if ea above is inside this memory region. -;feature_safe_memory_start=0x880000 -;feature_safe_memory_size=0x80000 -; R = read only bus error, W = write only bus error, empty or RW = both. +feature_safe_memory_start=0x880000 +feature_safe_memory_size=0x80000 +; R = data read only bus error +; W = data write only bus error +; P = prefetch bus error +; empty or RWP = both. ; if enabled, all tests that don't generate matching bus error are skipped. -;feature_safe_memory_mode=R +feature_safe_memory_mode=R ; force odd user stack ; 0 = even stack diff --git a/cputest/main.c b/cputest/main.c index 0808f028..0eb1e8aa 100644 --- a/cputest/main.c +++ b/cputest/main.c @@ -95,7 +95,7 @@ static int low_memory_offset; static int high_memory_offset; static uae_u32 vbr[256]; -static int exceptioncount[2][128]; +static int exceptioncount[3][128]; static int supercnt; static uae_u32 endpc; @@ -214,6 +214,7 @@ static struct accesshistory ahist[MAX_ACCESSHIST]; static int is_valid_test_addr_read(uae_u32 a) { + a &= addressing_mask; if ((uae_u8 *)a >= safe_memory_start && (uae_u8 *)a < safe_memory_end && (safe_memory_mode & 1)) return 0; return (a >= test_low_memory_start && a < test_low_memory_end && test_low_memory_start != 0xffffffff) || @@ -223,6 +224,7 @@ static int is_valid_test_addr_read(uae_u32 a) static int is_valid_test_addr_readwrite(uae_u32 a) { + a &= addressing_mask; if ((uae_u8 *)a >= safe_memory_start && (uae_u8 *)a < safe_memory_end) return 0; return (a >= test_low_memory_start && a < test_low_memory_end && test_low_memory_start != 0xffffffff) || @@ -943,7 +945,7 @@ static void addinfo_bytes(char *name, uae_u8 *src, uae_u32 address, int offset, *outbp++ = '*'; else if (cnt > 0) *outbp++ = '.'; - if ((uae_u8*)address >= safe_memory_start && (uae_u8*)address < safe_memory_end && (safe_memory_mode & 1)) { + if ((uae_u8*)address >= safe_memory_start && (uae_u8*)address < safe_memory_end && (safe_memory_mode & (1 | 4))) { outbp[0] = '?'; outbp[1] = '?'; } else { @@ -1053,8 +1055,8 @@ static void addinfo(void) uae_u8 *b = (uae_u8 *)regs.branchtarget - SIZE_STORED_ADDRESS_OFFSET; addinfo_bytes("B", b, regs.branchtarget, -SIZE_STORED_ADDRESS_OFFSET, SIZE_STORED_ADDRESS); } - sprintf(outbp, "ENDPC=%08lx\n", endpc); - outbp += strlen(outbp); + //sprintf(outbp, "ENDPC=%08lx\n", endpc); + //outbp += strlen(outbp); } struct srbit @@ -1189,7 +1191,7 @@ static uae_u8 *validate_exception(struct registers *regs, uae_u8 *p, int excnum, uae_u32 v; uae_u8 excdatalen = *p++; int size; - int excrw = 0; + int excrwp = 0; if (!excdatalen) { return p; @@ -1273,7 +1275,9 @@ static uae_u8 *validate_exception(struct registers *regs, uae_u8 *p, int excnum, uae_u8 opcode1 = p[2]; exc[0] = opcode0; exc[1] = (opcode1 & ~0x1f) | p[0]; - excrw = (p[0] & 0x10) == 0; + excrwp = ((p[0] & 0x10) == 0) ? 1 : 0; + if (p[0] & 2) + excrwp = 2; p += 3; // access address v = opcode_memory_addr; @@ -1330,7 +1334,9 @@ static uae_u8 *validate_exception(struct registers *regs, uae_u8 *p, int excnum, case 8: exc[8] = *p++; exc[9] = *p++; - excrw = (exc[8] & 1) == 0; + excrwp = ((exc[8] & 1) == 0) ? 1 : 0; + if (exc[9] & 2) + excrwp = 2; v = opcode_memory_addr; p = restore_rel_ordered(p, &v); pl(exc + 10, v); @@ -1373,7 +1379,7 @@ static uae_u8 *validate_exception(struct registers *regs, uae_u8 *p, int excnum, exclen = last_exception_len; } - exceptioncount[excrw][*gotexcnum]++; + exceptioncount[excrwp][*gotexcnum]++; if (exclen == 0 || *gotexcnum != excnum) return p; @@ -2185,9 +2191,9 @@ static int test_mnemo(const char *path, const char *opcode) printf("%lu ", testcnt); printf("S=%ld", supercnt); for (int i = 0; i < 128; i++) { - if (exceptioncount[0][i] || exceptioncount[1][i]) { + if (exceptioncount[0][i] || exceptioncount[1][i] || exceptioncount[2][i]) { if (i == 2 || i == 3) { - printf(" E%02d=%ld/%ld", i, exceptioncount[0][i], exceptioncount[1][i]); + printf(" E%02d=%ld/%ld/%ld", i, exceptioncount[0][i], exceptioncount[1][i], exceptioncount[2][i]); } else { printf(" E%02d=%ld", i, exceptioncount[0][i]); } diff --git a/gencpu.cpp b/gencpu.cpp index 90c5ba09..e438cbfc 100644 --- a/gencpu.cpp +++ b/gencpu.cpp @@ -511,6 +511,7 @@ static void add_mmu040_movem (int movem) static char bus_error_text[200]; static int bus_error_specials; +static char bus_error_code[1000]; static void do_instruction_buserror(void) { @@ -518,6 +519,8 @@ static void do_instruction_buserror(void) return; if (bus_error_text[0]) { printf("\tif(cpu_bus_error) {\n"); + if (bus_error_code[0]) + printf("%s", bus_error_code); printf("%s", bus_error_text); printf("\t\tgoto %s;\n", endlabelstr); need_endlabel = 1; @@ -882,7 +885,11 @@ static void fill_prefetch_full_000_special(void) irc2ir(); if (using_bus_error) { printf("\topcode = regs.ir;\n"); - printf("\tif(regs.t1) opcode |= 0x10000;\n"); + if (g_instr->mnemo == i_RTE) { + printf("\tif(oldt1) opcode |= 0x10000;\n"); + } else { + printf("\tif(regs.t1) opcode |= 0x10000;\n"); + } } printf("\t%s (%d);\n", prefetch_word, 2); check_prefetch_bus_error(-2, -1); @@ -934,19 +941,38 @@ static void dummy_prefetch (void) insn_n_cycles += 4; } -static void fill_prefetch_next (void) +static void fill_prefetch_next_noopcodecopy(const char *format, ...) { if (using_prefetch) { irc2ir(); if (using_bus_error) { - printf("\topcode = regs.ir;\n"); + bus_error_code[0] = 0; + if (format) { + va_list parms; + va_start(parms, format); + _vsnprintf(bus_error_code, sizeof(bus_error_code) - 1, format, parms); + va_end(parms); + } + printf("\topcode |= 0x20000;\n"); + } + fill_prefetch_1(m68k_pc_offset + 2); + } +} + +static void fill_prefetch_next(void) +{ + if (using_prefetch) { + irc2ir(); + if (using_bus_error) { + int mode = g_instr->smode; + if (mode == Aind || mode == Apdi || mode == Aipi || mode == Ad16 || mode == PC16 || mode == Ad8r || mode == PC8r || mode == absw || mode == absl) { + printf("\topcode |= 0x20000;\n"); + } else { + printf("\topcode = regs.ir;\n"); + } } fill_prefetch_1(m68k_pc_offset + 2); } -// if (using_prefetch_020) { -// printf ("\t%s (%d);\n", prefetch_word, m68k_pc_offset); -// did_prefetch = 1; -// } } static void fill_prefetch_next_skipopcode(void) @@ -4039,6 +4065,7 @@ static void gen_opcode (unsigned int opcode) m68k_pc_offset = 2; g_instr = curi; g_srcname[0] = 0; + bus_error_code[0] = 0; // do not unnecessarily create useless mmuop030 // functions when CPU is not 68030 @@ -4325,23 +4352,33 @@ static void gen_opcode (unsigned int opcode) break; case i_NEG: genamode (curi, curi->smode, "srcreg", curi->size, "src", 1, 0, GF_RMW); - fill_prefetch_next (); + genflags(flag_sub, curi->size, "dst", "src", "0"); + if (curi->smode == Dreg) { + genastore_rev("dst", curi->smode, "srcreg", curi->size, "src"); + } + fill_prefetch_next(); if (isreg (curi->smode) && curi->size == sz_long) addcycles000 (2); start_brace (); - genflags (flag_sub, curi->size, "dst", "src", "0"); - genastore_rev ("dst", curi->smode, "srcreg", curi->size, "src"); + if (curi->smode != Dreg) { + genastore_rev("dst", curi->smode, "srcreg", curi->size, "src"); + } break; case i_NEGX: genamode (curi, curi->smode, "srcreg", curi->size, "src", 1, 0, GF_RMW); + printf("\tuae_u32 newv = 0 - src - (GET_XFLG () ? 1 : 0);\n"); + genflags(flag_subx, curi->size, "newv", "src", "0"); + genflags(flag_zn, curi->size, "newv", "", ""); + if (curi->smode == Dreg) { + genastore_rev("newv", curi->smode, "srcreg", curi->size, "src"); + } fill_prefetch_next (); if (isreg (curi->smode) && curi->size == sz_long) addcycles000 (2); start_brace (); - printf ("\tuae_u32 newv = 0 - src - (GET_XFLG () ? 1 : 0);\n"); - genflags (flag_subx, curi->size, "newv", "src", "0"); - genflags (flag_zn, curi->size, "newv", "", ""); - genastore_rev ("newv", curi->smode, "srcreg", curi->size, "src"); + if (curi->smode != Dreg) { + genastore_rev("newv", curi->smode, "srcreg", curi->size, "src"); + } break; case i_NBCD: genamode (curi, curi->smode, "srcreg", curi->size, "src", 1, 0, GF_RMW); @@ -4382,11 +4419,16 @@ static void gen_opcode (unsigned int opcode) next_level_000 (); if (cpu_level == 0) { genamode(curi, curi->smode, "srcreg", curi->size, "src", 1, 0, 0); + genflags(flag_logical, curi->size, "0", "", ""); + if (curi->smode == Dreg) { + genastore_rev("0", curi->smode, "srcreg", curi->size, "src"); + } fill_prefetch_next(); if (isreg(curi->smode) && curi->size == sz_long) addcycles000(2); - genflags(flag_logical, curi->size, "0", "", ""); - genastore_rev("0", curi->smode, "srcreg", curi->size, "src"); + if (curi->smode != Dreg) { + genastore_rev("0", curi->smode, "srcreg", curi->size, "src"); + } } else if (cpu_level == 1) { genamode(curi, curi->smode, "srcreg", curi->size, "src", 3, 0, 0); if (isreg(curi->smode) && curi->size == sz_long) @@ -4412,13 +4454,18 @@ static void gen_opcode (unsigned int opcode) break; case i_NOT: genamode (curi, curi->smode, "srcreg", curi->size, "src", 1, 0, GF_RMW); + printf("\tuae_u32 dst = ~src;\n"); + genflags(flag_logical, curi->size, "dst", "", ""); + if (curi->smode == Dreg) { + genastore_rev("dst", curi->smode, "srcreg", curi->size, "src"); + } fill_prefetch_next (); if (isreg (curi->smode) && curi->size == sz_long) addcycles000 (2); start_brace (); - printf ("\tuae_u32 dst = ~src;\n"); - genflags (flag_logical, curi->size, "dst", "", ""); - genastore_rev ("dst", curi->smode, "srcreg", curi->size, "src"); + if (curi->smode != Dreg) { + genastore_rev("dst", curi->smode, "srcreg", curi->size, "src"); + } break; case i_TST: genamode (curi, curi->smode, "srcreg", curi->size, "src", 1, 0, 0); @@ -4891,6 +4938,7 @@ static void gen_opcode (unsigned int opcode) genamode (NULL, Aipi, "7", sz_word, "sr", 1, 0, GF_NOREFILL); genamode (NULL, Aipi, "7", sz_long, "pc", 1, 0, GF_NOREFILL); printf("\tuaecptr oldpc = %s;\n", getpc); + printf("\tuae_u16 oldt1 = regs.t1;\n"); printf("\tregs.sr = sr;\n"); makefromsr(); printf("\tif (pc & 1) {\n"); @@ -4898,6 +4946,7 @@ static void gen_opcode (unsigned int opcode) printf("\t\tgoto %s;\n", endlabelstr); printf("\t}\n"); setpc ("pc"); + printf("\topcode |= 0x20000;\n"); if (using_debugmem) { printf("\tbranch_stack_pop_rte(oldpc);\n"); } @@ -4906,6 +4955,7 @@ static void gen_opcode (unsigned int opcode) int old_brace_level = n_braces; printf("\tuaecptr oldpc = %s;\n", getpc); printf ("\tuae_u16 newsr; uae_u32 newpc;\n"); + printf("\tuae_u16 oldt1 = regs.t1;\n"); printf ("\tfor (;;) {\n"); printf ("\t\tuaecptr a = m68k_areg (regs, 7);\n"); printf ("\t\tuae_u16 sr = %s (a);\n", srcw); @@ -5179,9 +5229,9 @@ static void gen_opcode (unsigned int opcode) next_level_040_to_030(); break; case i_TRAPV: - sync_m68k_pc (); - fill_prefetch_next (); - printf ("\tif (GET_VFLG ()) {\n"); + sync_m68k_pc(); + fill_prefetch_next_noopcodecopy("\t\tif (GET_VFLG()) { ; } else opcode = regs.ir;\n"); + printf ("\tif (GET_VFLG()) {\n"); printf ("\t\tException_cpu(7);\n"); printf ("\t\tgoto %s;\n", endlabelstr); printf ("\t}\n"); @@ -5800,20 +5850,21 @@ bccl_not68020: genamodedual (curi, curi->smode, "srcreg", curi->size, "cnt", 1, 0, curi->dmode, "dstreg", curi->size, "data", 1, GF_RMW); - //genamode (curi, curi->smode, "srcreg", curi->size, "cnt", 1, 0, 0); - //genamode (curi, curi->dmode, "dstreg", curi->size, "data", 1, 0, GF_RMW); - fill_prefetch_next(); - start_brace (); switch (curi->size) { case sz_byte: printf ("\tuae_u32 val = (uae_u8)data;\n"); break; case sz_word: printf ("\tuae_u32 val = (uae_u16)data;\n"); break; case sz_long: printf ("\tuae_u32 val = data;\n"); break; default: term (); } + printf("\tCLEAR_CZNV();\n"); + if (curi->size == sz_long) { + fill_prefetch_next_noopcodecopy("\t\tSET_NFLG(val & 0x8000);SET_ZFLG(!(val & 0xffff));\n"); + } else { + fill_prefetch_next_noopcodecopy("\t\tSET_ZFLG(!(val & %s));SET_NFLG(val & %s);\n", bit_mask(curi->size), cmask(curi->size)); + } printf ("\tuae_u32 sign = (%s & val) >> %d;\n", cmask (curi->size), bit_size (curi->size) - 1); printf ("\tint ccnt = cnt & 63;\n"); printf ("\tcnt &= 63;\n"); - printf ("\tCLEAR_CZNV ();\n"); printf ("\tif (cnt >= %d) {\n", bit_size (curi->size)); printf ("\t\tval = %s & (uae_u32)(0 - sign);\n", bit_mask (curi->size)); printf ("\t\tSET_CFLG (sign);\n"); @@ -5839,19 +5890,20 @@ bccl_not68020: genamodedual (curi, curi->smode, "srcreg", curi->size, "cnt", 1, 0, curi->dmode, "dstreg", curi->size, "data", 1, GF_RMW); - //genamode (curi, curi->smode, "srcreg", curi->size, "cnt", 1, 0, 0); - //genamode (curi, curi->dmode, "dstreg", curi->size, "data", 1, 0, GF_RMW); - fill_prefetch_next(); - start_brace (); switch (curi->size) { case sz_byte: printf ("\tuae_u32 val = (uae_u8)data;\n"); break; case sz_word: printf ("\tuae_u32 val = (uae_u16)data;\n"); break; case sz_long: printf ("\tuae_u32 val = data;\n"); break; default: term (); } + printf("\tCLEAR_CZNV();\n"); + if (curi->size == sz_long) { + fill_prefetch_next_noopcodecopy("\t\tSET_NFLG(val & 0x8000);SET_ZFLG(!(val & 0xffff));\n"); + } else { + fill_prefetch_next_noopcodecopy("\t\tSET_ZFLG(!(val & %s));SET_NFLG(val & %s);\n", bit_mask(curi->size), cmask(curi->size)); + } printf ("\tint ccnt = cnt & 63;\n"); printf ("\tcnt &= 63;\n"); - printf ("\tCLEAR_CZNV ();\n"); printf ("\tif (cnt >= %d) {\n", bit_size (curi->size)); printf ("\t\tSET_VFLG (val != 0);\n"); printf ("\t\tSET_CFLG (cnt == %d ? val & 1 : 0);\n", @@ -5881,19 +5933,20 @@ bccl_not68020: genamodedual (curi, curi->smode, "srcreg", curi->size, "cnt", 1, 0, curi->dmode, "dstreg", curi->size, "data", 1, GF_RMW); - //genamode (curi, curi->smode, "srcreg", curi->size, "cnt", 1, 0, 0); - //genamode (curi, curi->dmode, "dstreg", curi->size, "data", 1, 0, GF_RMW); - fill_prefetch_next(); - start_brace (); switch (curi->size) { case sz_byte: printf ("\tuae_u32 val = (uae_u8)data;\n"); break; case sz_word: printf ("\tuae_u32 val = (uae_u16)data;\n"); break; case sz_long: printf ("\tuae_u32 val = data;\n"); break; default: term (); } + printf("\tCLEAR_CZNV();\n"); + if (curi->size == sz_long) { + fill_prefetch_next_noopcodecopy("\t\tSET_NFLG(val & 0x8000);SET_ZFLG(!(val & 0xffff));\n"); + } else { + fill_prefetch_next_noopcodecopy("\t\tSET_ZFLG(!(val & %s));SET_NFLG(val & %s);\n", bit_mask(curi->size), cmask(curi->size)); + } printf ("\tint ccnt = cnt & 63;\n"); printf ("\tcnt &= 63;\n"); - printf ("\tCLEAR_CZNV ();\n"); printf ("\tif (cnt >= %d) {\n", bit_size (curi->size)); printf ("\t\tSET_CFLG ((cnt == %d) & (val >> %d));\n", bit_size (curi->size), bit_size (curi->size) - 1); @@ -5916,54 +5969,56 @@ bccl_not68020: genamodedual (curi, curi->smode, "srcreg", curi->size, "cnt", 1, 0, curi->dmode, "dstreg", curi->size, "data", 1, GF_RMW); - //genamode (curi, curi->smode, "srcreg", curi->size, "cnt", 1, 0, 0); - //genamode (curi, curi->dmode, "dstreg", curi->size, "data", 1, 0, GF_RMW); - fill_prefetch_next(); - start_brace (); switch (curi->size) { case sz_byte: printf ("\tuae_u32 val = (uae_u8)data;\n"); break; case sz_word: printf ("\tuae_u32 val = (uae_u16)data;\n"); break; case sz_long: printf ("\tuae_u32 val = data;\n"); break; default: term (); } - printf ("\tint ccnt = cnt & 63;\n"); - printf ("\tcnt &= 63;\n"); - printf ("\tCLEAR_CZNV ();\n"); - printf ("\tif (cnt >= %d) {\n", bit_size (curi->size)); - printf ("\t\tSET_CFLG (cnt == %d ? val & 1 : 0);\n", bit_size (curi->size)); - duplicate_carry (1); - printf ("\t\tval = 0;\n"); - if (source_is_imm1_8 (curi)) - printf ("\t} else {\n"); + printf("\tCLEAR_CZNV();\n"); + if (curi->size == sz_long) { + fill_prefetch_next_noopcodecopy("\t\tSET_NFLG(val & 0x8000);SET_ZFLG(!(val & 0xffff));\n"); + } else { + fill_prefetch_next_noopcodecopy("\t\tSET_ZFLG(!(val & %s));SET_NFLG(val & %s);\n", bit_mask(curi->size), cmask(curi->size)); + } + printf("\tint ccnt = cnt & 63;\n"); + printf("\tcnt &= 63;\n"); + printf("\tif (cnt >= %d) {\n", bit_size (curi->size)); + printf("\t\tSET_CFLG (cnt == %d ? val & 1 : 0);\n", bit_size(curi->size)); + duplicate_carry(1); + printf("\t\tval = 0;\n"); + if (source_is_imm1_8(curi)) + printf("\t} else {\n"); else - printf ("\t} else if (cnt > 0) {\n"); - printf ("\t\tval <<= (cnt - 1);\n"); - printf ("\t\tSET_CFLG ((val & %s) >> %d);\n", cmask (curi->size), bit_size (curi->size) - 1); + printf("\t} else if (cnt > 0) {\n"); + printf("\t\tval <<= (cnt - 1);\n"); + printf("\t\tSET_CFLG((val & %s) >> %d);\n", cmask(curi->size), bit_size(curi->size) - 1); duplicate_carry (1); - printf ("\t\tval <<= 1;\n"); - printf ("\tval &= %s;\n", bit_mask (curi->size)); - printf ("\t}\n"); - genflags (flag_logical_noclobber, curi->size, "val", "", ""); - shift_ce (curi->dmode, curi->size); - genastore ("val", curi->dmode, "dstreg", curi->size, "data"); + printf("\t\tval <<= 1;\n"); + printf("\tval &= %s;\n", bit_mask (curi->size)); + printf("\t}\n"); + genflags(flag_logical_noclobber, curi->size, "val", "", ""); + shift_ce(curi->dmode, curi->size); + genastore("val", curi->dmode, "dstreg", curi->size, "data"); break; case i_ROL: genamodedual (curi, curi->smode, "srcreg", curi->size, "cnt", 1, 0, curi->dmode, "dstreg", curi->size, "data", 1, GF_RMW); - //genamode (curi, curi->smode, "srcreg", curi->size, "cnt", 1, 0, 0); - //genamode (curi, curi->dmode, "dstreg", curi->size, "data", 1, 0, GF_RMW); - fill_prefetch_next (); - start_brace (); switch (curi->size) { case sz_byte: printf ("\tuae_u32 val = (uae_u8)data;\n"); break; case sz_word: printf ("\tuae_u32 val = (uae_u16)data;\n"); break; case sz_long: printf ("\tuae_u32 val = data;\n"); break; default: term (); } + printf("\tCLEAR_CZNV();\n"); + if (curi->size == sz_long) { + fill_prefetch_next_noopcodecopy("\t\tSET_NFLG(val & 0x8000);SET_ZFLG(!(val & 0xffff));\n"); + } else { + fill_prefetch_next_noopcodecopy("\t\tSET_ZFLG(!(val & %s));SET_NFLG(val & %s);\n", bit_mask(curi->size), cmask(curi->size)); + } printf ("\tint ccnt = cnt & 63;\n"); printf ("\tcnt &= 63;\n"); - printf ("\tCLEAR_CZNV ();\n"); if (source_is_imm1_8 (curi)) printf ("{"); else @@ -5984,19 +6039,20 @@ bccl_not68020: genamodedual (curi, curi->smode, "srcreg", curi->size, "cnt", 1, 0, curi->dmode, "dstreg", curi->size, "data", 1, GF_RMW); - //genamode (curi, curi->smode, "srcreg", curi->size, "cnt", 1, 0, 0); - //genamode (curi, curi->dmode, "dstreg", curi->size, "data", 1, 0, GF_RMW); - fill_prefetch_next (); - start_brace (); switch (curi->size) { case sz_byte: printf ("\tuae_u32 val = (uae_u8)data;\n"); break; case sz_word: printf ("\tuae_u32 val = (uae_u16)data;\n"); break; case sz_long: printf ("\tuae_u32 val = data;\n"); break; default: term (); } + printf("\tCLEAR_CZNV();\n"); + if (curi->size == sz_long) { + fill_prefetch_next_noopcodecopy("\t\tSET_NFLG(val & 0x8000);SET_ZFLG(!(val & 0xffff));\n"); + } else { + fill_prefetch_next_noopcodecopy("\t\tSET_ZFLG(!(val & %s));SET_NFLG(val & %s);\n", bit_mask(curi->size), cmask(curi->size)); + } printf ("\tint ccnt = cnt & 63;\n"); printf ("\tcnt &= 63;\n"); - printf ("\tCLEAR_CZNV ();\n"); if (source_is_imm1_8 (curi)) printf ("{"); else @@ -6017,19 +6073,20 @@ bccl_not68020: genamodedual (curi, curi->smode, "srcreg", curi->size, "cnt", 1, 0, curi->dmode, "dstreg", curi->size, "data", 1, GF_RMW); - //genamode (curi, curi->smode, "srcreg", curi->size, "cnt", 1, 0, 0); - //genamode (curi, curi->dmode, "dstreg", curi->size, "data", 1, 0, GF_RMW); - fill_prefetch_next (); - start_brace (); switch (curi->size) { case sz_byte: printf ("\tuae_u32 val = (uae_u8)data;\n"); break; case sz_word: printf ("\tuae_u32 val = (uae_u16)data;\n"); break; case sz_long: printf ("\tuae_u32 val = data;\n"); break; default: term (); } + printf("\tCLEAR_CZNV();\n"); + if (curi->size == sz_long) { + fill_prefetch_next_noopcodecopy("\t\tSET_NFLG(val & 0x8000);SET_ZFLG(!(val & 0xffff));SET_CFLG(GET_XFLG());\n"); + } else { + fill_prefetch_next_noopcodecopy("\t\tSET_ZFLG(!(val & %s));SET_NFLG(val & %s);SET_CFLG(GET_XFLG());\n", bit_mask(curi->size), cmask(curi->size)); + } printf ("\tint ccnt = cnt & 63;\n"); printf ("\tcnt &= 63;\n"); - printf ("\tCLEAR_CZNV ();\n"); if (source_is_imm1_8 (curi)) printf ("{"); else { @@ -6053,19 +6110,20 @@ bccl_not68020: genamodedual (curi, curi->smode, "srcreg", curi->size, "cnt", 1, 0, curi->dmode, "dstreg", curi->size, "data", 1, GF_RMW); - //genamode (curi, curi->smode, "srcreg", curi->size, "cnt", 1, 0, 0); - //genamode (curi, curi->dmode, "dstreg", curi->size, "data", 1, 0, GF_RMW); - fill_prefetch_next (); - start_brace (); switch (curi->size) { case sz_byte: printf ("\tuae_u32 val = (uae_u8)data;\n"); break; case sz_word: printf ("\tuae_u32 val = (uae_u16)data;\n"); break; case sz_long: printf ("\tuae_u32 val = data;\n"); break; default: term (); } + printf("\tCLEAR_CZNV ();\n"); + if (curi->size == sz_long) { + fill_prefetch_next_noopcodecopy("\t\tSET_NFLG(val & 0x8000);SET_ZFLG(!(val & 0xffff));SET_CFLG(GET_XFLG());\n"); + } else { + fill_prefetch_next_noopcodecopy("\t\tSET_ZFLG(!(val & %s));SET_NFLG(val & %s);SET_CFLG(GET_XFLG());\n", bit_mask(curi->size), cmask(curi->size)); + } printf ("\tint ccnt = cnt & 63;\n"); printf ("\tcnt &= 63;\n"); - printf ("\tCLEAR_CZNV ();\n"); if (source_is_imm1_8 (curi)) printf ("{"); else { @@ -6090,14 +6148,13 @@ bccl_not68020: break; case i_ASRW: genamode (curi, curi->smode, "srcreg", curi->size, "data", 1, 0, GF_RMW); - fill_prefetch_next (); - start_brace (); switch (curi->size) { case sz_byte: printf ("\tuae_u32 val = (uae_u8)data;\n"); break; case sz_word: printf ("\tuae_u32 val = (uae_u16)data;\n"); break; case sz_long: printf ("\tuae_u32 val = data;\n"); break; default: term (); } + fill_prefetch_next_noopcodecopy("\t\tCLEAR_CZNV();SET_CFLG(val & 1);SET_ZFLG(!(val >> 1));SET_NFLG(val & 0x8000);SET_XFLG(GET_CFLG());\n"); printf ("\tuae_u32 sign = %s & val;\n", cmask (curi->size)); printf ("\tuae_u32 cflg = val & 1;\n"); printf ("\tval = (val >> 1) | sign;\n"); @@ -6108,14 +6165,13 @@ bccl_not68020: break; case i_ASLW: genamode (curi, curi->smode, "srcreg", curi->size, "data", 1, 0, GF_RMW); - fill_prefetch_next (); - start_brace (); switch (curi->size) { case sz_byte: printf ("\tuae_u32 val = (uae_u8)data;\n"); break; case sz_word: printf ("\tuae_u32 val = (uae_u16)data;\n"); break; case sz_long: printf ("\tuae_u32 val = data;\n"); break; default: term (); } + fill_prefetch_next_noopcodecopy("\t\tCLEAR_CZNV();SET_CFLG(val & %s);SET_ZFLG(!((val << 1) & 0x7fff));SET_NFLG(val & 0x4000);SET_XFLG(GET_CFLG());SET_VFLG((val & 0x8000) != ((val << 1) & 0x8000));\n", cmask(curi->size)); printf ("\tuae_u32 sign = %s & val;\n", cmask (curi->size)); printf ("\tuae_u32 sign2;\n"); printf ("\tval <<= 1;\n"); @@ -6128,14 +6184,13 @@ bccl_not68020: break; case i_LSRW: genamode (curi, curi->smode, "srcreg", curi->size, "data", 1, 0, GF_RMW); - fill_prefetch_next (); - start_brace (); switch (curi->size) { case sz_byte: printf ("\tuae_u32 val = (uae_u8)data;\n"); break; case sz_word: printf ("\tuae_u32 val = (uae_u16)data;\n"); break; case sz_long: printf ("\tuae_u32 val = data;\n"); break; default: term (); } + fill_prefetch_next_noopcodecopy("\t\tCLEAR_CZNV();SET_CFLG(val & 1);SET_ZFLG(!(val >> 1));SET_NFLG(0);SET_XFLG(GET_CFLG());\n"); printf ("\tuae_u32 carry = val & 1;\n"); printf ("\tval >>= 1;\n"); genflags (flag_logical, curi->size, "val", "", ""); @@ -6145,14 +6200,13 @@ bccl_not68020: break; case i_LSLW: genamode (curi, curi->smode, "srcreg", curi->size, "data", 1, 0, GF_RMW); - fill_prefetch_next (); - start_brace (); switch (curi->size) { case sz_byte: printf ("\tuae_u8 val = data;\n"); break; case sz_word: printf ("\tuae_u16 val = data;\n"); break; case sz_long: printf ("\tuae_u32 val = data;\n"); break; default: term (); } + fill_prefetch_next_noopcodecopy("\t\tCLEAR_CZNV();SET_CFLG(val & %s);SET_ZFLG(!(val << 1));SET_NFLG(val & 0x4000);SET_XFLG(GET_CFLG());\n", cmask(curi->size)); printf ("\tuae_u32 carry = val & %s;\n", cmask (curi->size)); printf ("\tval <<= 1;\n"); genflags (flag_logical, curi->size, "val", "", ""); @@ -6162,14 +6216,13 @@ bccl_not68020: break; case i_ROLW: genamode (curi, curi->smode, "srcreg", curi->size, "data", 1, 0, GF_RMW); - fill_prefetch_next (); - start_brace (); switch (curi->size) { case sz_byte: printf ("\tuae_u8 val = data;\n"); break; case sz_word: printf ("\tuae_u16 val = data;\n"); break; case sz_long: printf ("\tuae_u32 val = data;\n"); break; default: term (); } + fill_prefetch_next_noopcodecopy("\t\tCLEAR_CZNV();SET_CFLG(val & %s);SET_ZFLG(!val);SET_NFLG(val & 0x4000);\n", cmask(curi->size)); printf ("\tuae_u32 carry = val & %s;\n", cmask (curi->size)); printf ("\tval <<= 1;\n"); printf ("\tif (carry) val |= 1;\n"); @@ -6179,14 +6232,13 @@ bccl_not68020: break; case i_RORW: genamode (curi, curi->smode, "srcreg", curi->size, "data", 1, 0, GF_RMW); - fill_prefetch_next (); - start_brace (); switch (curi->size) { case sz_byte: printf ("\tuae_u8 val = data;\n"); break; case sz_word: printf ("\tuae_u16 val = data;\n"); break; case sz_long: printf ("\tuae_u32 val = data;\n"); break; default: term (); } + fill_prefetch_next_noopcodecopy("\t\tCLEAR_CZNV();SET_CFLG(val & 1);SET_ZFLG(!val);SET_NFLG(val & 0x0001);\n"); printf ("\tuae_u32 carry = val & 1;\n"); printf ("\tval >>= 1;\n"); printf ("\tif (carry) val |= %s;\n", cmask (curi->size)); @@ -6196,14 +6248,13 @@ bccl_not68020: break; case i_ROXLW: genamode (curi, curi->smode, "srcreg", curi->size, "data", 1, 0, GF_RMW); - fill_prefetch_next (); - start_brace (); switch (curi->size) { case sz_byte: printf ("\tuae_u8 val = data;\n"); break; case sz_word: printf ("\tuae_u16 val = data;\n"); break; case sz_long: printf ("\tuae_u32 val = data;\n"); break; default: term (); } + fill_prefetch_next_noopcodecopy("\t\tCLEAR_CZNV();SET_CFLG(val & 0x8000);SET_ZFLG(!((val << 1) | GET_XFLG()));SET_NFLG(val & 0x4000);SET_XFLG(GET_CFLG());\n", cmask(curi->size)); printf ("\tuae_u32 carry = val & %s;\n", cmask (curi->size)); printf ("\tval <<= 1;\n"); printf ("\tif (GET_XFLG ()) val |= 1;\n"); @@ -6214,14 +6265,13 @@ bccl_not68020: break; case i_ROXRW: genamode (curi, curi->smode, "srcreg", curi->size, "data", 1, 0, GF_RMW); - fill_prefetch_next (); - start_brace (); switch (curi->size) { case sz_byte: printf ("\tuae_u8 val = data;\n"); break; case sz_word: printf ("\tuae_u16 val = data;\n"); break; case sz_long: printf ("\tuae_u32 val = data;\n"); break; default: term (); } + fill_prefetch_next_noopcodecopy("\t\tCLEAR_CZNV();SET_CFLG(val & 1);SET_ZFLG(!((val >> 1) | GET_XFLG()));SET_NFLG(GET_XFLG());SET_XFLG(GET_CFLG());\n", cmask(curi->size)); printf ("\tuae_u32 carry = val & 1;\n"); printf ("\tval >>= 1;\n"); printf ("\tif (GET_XFLG ()) val |= %s;\n", cmask (curi->size)); -- 2.47.3