From 6bb71af5c2efee3a1fb3f2e220ed51c5bfc67350 Mon Sep 17 00:00:00 2001 From: Toni Wilen Date: Mon, 27 Jul 2020 19:56:31 +0300 Subject: [PATCH] Aranym JIT merge. --- build68k.cpp | 23 +- fpp.cpp | 2 +- gencpu.cpp | 275 +- include/debug.h | 7 + include/newcpu.h | 84 +- include/readcpu.h | 27 +- include/sysdeps.h | 6 +- include/uae/memory.h | 2 + jit/codegen_x86.cpp | 2412 +-------------- jit/codegen_x86.h | 54 +- jit/compemu.h | 119 +- jit/compemu_fpp.cpp | 3007 +++++++++++-------- jit/compemu_midfunc_x86.cpp | 378 +-- jit/compemu_midfunc_x86.h | 27 +- jit/compemu_support.cpp | 925 ++++-- jit/gencomp.cpp | 5633 +++++++++++++++++------------------ jit/memory-uae.h | 2 + main.cpp | 1 + memory.cpp | 2 +- newcpu.cpp | 163 +- newcpu_common.cpp | 14 +- od-win32/machdep/m68k.cpp | 95 +- od-win32/machdep/m68k.h | 113 +- od-win32/machdep/maccess.h | 20 + od-win32/sysconfig.h | 4 +- readcpu.cpp | 141 +- table68k | 484 +-- 27 files changed, 6538 insertions(+), 7482 deletions(-) create mode 100644 include/uae/memory.h create mode 100644 jit/memory-uae.h diff --git a/build68k.cpp b/build68k.cpp index c83e99f6..82ad4fb3 100644 --- a/build68k.cpp +++ b/build68k.cpp @@ -81,6 +81,7 @@ int main(int argc, char **argv) char opcstr[256]; int bitpos[16]; int flagset[5], flaguse[5]; + char cflow; unsigned int bitmask,bitpattern; int n_variable; @@ -205,6 +206,26 @@ int main(int argc, char **argv) } } + getnextch(); + while (isspace(nextch)) + getnextch(); + + if (nextch != ':') /* Get control flow information */ + abort(); + + cflow = 0; + for (i = 0; i < 2; i++) { + getnextch(); + switch (nextch) { + case '-': break; + case 'R': cflow |= fl_return; break; + case 'B': cflow |= fl_branch; break; + case 'J': cflow |= fl_jump; break; + case 'T': cflow |= fl_trap; break; + default: abort(); + } + } + getnextch(); while (isspace(nextch)) getnextch(); @@ -320,7 +341,7 @@ int main(int argc, char **argv) for(i = 0; i < 5; i++) { printf("{%d,%d}%s", flaguse[i], flagset[i], i == 4 ? "" : ","); } - printf("},0x%02x,_T(\"%s\"),%2d,%2d,%2d,%2d}", sduse, opstrp, head, tail, clocks, fetchmode); + printf("},0x%02x,0x%02x,_T(\"%s\"),%2d,%2d,%2d,%2d}", cflow, sduse, opstrp, head, tail, clocks, fetchmode); } printf("};\nint n_defs68k = %d;\n", no_insns); return 0; diff --git a/fpp.cpp b/fpp.cpp index 3b9446e2..3ac7286f 100644 --- a/fpp.cpp +++ b/fpp.cpp @@ -2304,7 +2304,7 @@ void fpuop_trapcc (uae_u32 opcode, uaecptr oldpc, uae_u16 extra) return; // BSUN fpu_op_illg (opcode, 0, false, regs.fpiar); } else if (cc) { - Exception (7); + Exception_cpu_oldpc(7, oldpc); } } diff --git a/gencpu.cpp b/gencpu.cpp index 65e63b2f..b4f3fe51 100644 --- a/gencpu.cpp +++ b/gencpu.cpp @@ -49,7 +49,12 @@ static int using_tracer; static int using_waitstates; static int using_simple_cycles; static int using_debugmem; +static int using_noflags; static int using_test; +static int using_nocycles; +static int using_get_word_unswapped; +static int using_optimized_flags; +static int need_exception_oldpc; static int need_special_fixup; static int cpu_level, cpu_generic; static int count_readp; @@ -63,9 +68,9 @@ static int memory_cycle_cnt; static int did_prefetch; static int ipl_fetched; static int opcode_nextcopy; +static int disable_noflags; static int do_always_dynamic_cycles; -static int optimized_flags; #define GF_APDI 0x00001 #define GF_AD8R 0x00002 @@ -590,6 +595,10 @@ static void returntail (bool iswrite) static void returncycles(int cycles) { + if (using_nocycles) { + out("return 0;\n"); + return; + } if (using_ce || using_ce020) { #if 0 if (tail_ce020 == 0) @@ -712,6 +721,9 @@ static void addcycles_ce020 (const char *name, int head, int tail, int cycles, i static void addcycles000_nonces(const char *sc) { + if (using_nocycles) { + return; + } if (using_simple_cycles || do_always_dynamic_cycles) { out("count_cycles += (%s) * CYCLE_UNIT / 2;\n", sc); count_ncycles++; @@ -719,6 +731,9 @@ static void addcycles000_nonces(const char *sc) } static void addcycles000_nonce(int c) { + if (using_nocycles) { + return; + } if (using_simple_cycles || do_always_dynamic_cycles) { out("count_cycles += %d * CYCLE_UNIT / 2;\n", c); count_ncycles++; @@ -787,6 +802,25 @@ static const char *bit_mask (int size) return 0; } +static void swap_opcode(void) +{ + if (using_get_word_unswapped) { + out("\topcode = do_byteswap_16(opcode);\n"); + } +} + +static void real_opcode(int *have) +{ + if (!*have) { + if (using_get_word_unswapped) { + out("\tuae_u32 real_opcode = do_byteswap_16(opcode);\n"); + } else { + out("\tuae_u32 real_opcode = opcode;\n"); + } + *have = 1; + } +} + static int mmu040_movem; static void start_mmu040_movem(int movem) { @@ -1857,7 +1891,7 @@ static void genflags(flagtypes type, wordsizes size, const char *value, const ch /* Temporarily deleted 68k/ARM flag optimizations. I'd prefer to have them in the appropriate m68k.h files and use just one copy of this code here. The API can be changed if necessary. */ - if (optimized_flags) { + if (using_optimized_flags) { switch (type) { case flag_add: case flag_sub: @@ -1876,9 +1910,9 @@ static void genflags(flagtypes type, wordsizes size, const char *value, const ch out("SET_CZNV(olcznv | FLAGVAL_Z);\n"); } else { switch (size) { - case sz_byte: out("optflag_testb(regs, (uae_s8)(%s));\n", value); break; - case sz_word: out("optflag_testw(regs, (uae_s16)(%s));\n", value); break; - case sz_long: out("optflag_testl(regs, (uae_s32)(%s));\n", value); break; + case sz_byte: out("optflag_testb((uae_s8)(%s));\n", value); break; + case sz_word: out("optflag_testw((uae_s16)(%s));\n", value); break; + case sz_long: out("optflag_testl((uae_s32)(%s));\n", value); break; default: term(); } out("IOR_CZNV(oldcznv);\n"); @@ -1890,41 +1924,39 @@ static void genflags(flagtypes type, wordsizes size, const char *value, const ch out("SET_CZNV(FLAGVAL_Z);\n"); } else { switch (size) { - case sz_byte: out("optflag_testb(regs, (uae_s8)(%s));\n", value); break; - case sz_word: out("optflag_testw(regs, (uae_s16)(%s));\n", value); break; - case sz_long: out("optflag_testl(regs, (uae_s32)(%s));\n", value); break; + case sz_byte: out("optflag_testb((uae_s8)(%s));\n", value); break; + case sz_word: out("optflag_testw((uae_s16)(%s));\n", value); break; + case sz_long: out("optflag_testl((uae_s32)(%s));\n", value); break; default: term(); } } return; - case flag_add: switch (size) { - case sz_byte: out("optflag_addb(regs, %s, (uae_s8)(%s), (uae_s8)(%s));\n", value, src, dst); break; - case sz_word: out("optflag_addw(regs, %s, (uae_s16)(%s), (uae_s16)(%s));\n", value, src, dst); break; - case sz_long: out("optflag_addl(regs, %s, (uae_s32)(%s), (uae_s32)(%s));\n", value, src, dst); break; + case sz_byte: out("optflag_addb(%s, (uae_s8)(%s), (uae_s8)(%s));\n", value, src, dst); break; + case sz_word: out("optflag_addw(%s, (uae_s16)(%s), (uae_s16)(%s));\n", value, src, dst); break; + case sz_long: out("optflag_addl(%s, (uae_s32)(%s), (uae_s32)(%s));\n", value, src, dst); break; default: term(); } return; case flag_sub: switch (size) { - case sz_byte: out("optflag_subb(regs, %s, (uae_s8)(%s), (uae_s8)(%s));\n", value, src, dst); break; - case sz_word: out("optflag_subw(regs, %s, (uae_s16)(%s), (uae_s16)(%s));\n", value, src, dst); break; - case sz_long: out("optflag_subl(regs, %s, (uae_s32)(%s), (uae_s32)(%s));\n", value, src, dst); break; + case sz_byte: out("optflag_subb(%s, (uae_s8)(%s), (uae_s8)(%s));\n", value, src, dst); break; + case sz_word: out("optflag_subw(%s, (uae_s16)(%s), (uae_s16)(%s));\n", value, src, dst); break; + case sz_long: out("optflag_subl(%s, (uae_s32)(%s), (uae_s32)(%s));\n", value, src, dst); break; default: term(); } return; case flag_cmp: switch (size) { - case sz_byte: out("optflag_cmpb(regs, (uae_s8)(%s), (uae_s8)(%s));\n", src, dst); break; - case sz_word: out("optflag_cmpw(regs, (uae_s16)(%s), (uae_s16)(%s));\n", src, dst); break; - case sz_long: out("optflag_cmpl(regs, (uae_s32)(%s), (uae_s32)(%s));\n", src, dst); break; + case sz_byte: out("optflag_cmpb((uae_s8)(%s), (uae_s8)(%s));\n", src, dst); break; + case sz_word: out("optflag_cmpw((uae_s16)(%s), (uae_s16)(%s));\n", src, dst); break; + case sz_long: out("optflag_cmpl((uae_s32)(%s), (uae_s32)(%s));\n", src, dst); break; default: term(); } return; - default: break; } @@ -4805,7 +4837,7 @@ static void bsetcycles (struct instr *curi) out("if (src > 15) %s(2);\n", do_cycles); } next_level_020_to_010(); - if ((using_simple_cycles || do_always_dynamic_cycles) && cpu_level <= 1) { + if ((using_simple_cycles || do_always_dynamic_cycles) && cpu_level <= 1 && !using_nocycles) { out("if (src > 15) {\n"); out("count_cycles += % d * CYCLE_UNIT / 2;\n", 2); out("}\n"); @@ -4821,6 +4853,20 @@ static int islongimm (struct instr *curi) return (curi->size == sz_long && (curi->smode == Dreg || curi->smode == imm || curi->smode == Areg)); } +static void exception_cpu(const char *s) +{ + if (need_exception_oldpc) { + out("Exception_cpu_oldpc(%s,oldpc);\n", s); + } else { + out("Exception_cpu(%s);\n", s); + } +} +static void exception_oldpc(void) +{ + if (need_exception_oldpc) { + out("uaecptr oldpc = %s;\n", getpc); + } +} static void resetvars (void) { @@ -6046,6 +6092,7 @@ static void gen_opcode (unsigned int opcode) genastore("dst", curi->dmode, "dstreg", curi->size, "dst"); break; case i_CMPM: + disable_noflags = 1; exception_pc_offset_extra_000 = 2; genamodedual(curi, curi->smode, "srcreg", curi->size, "src", 1, GF_AA, @@ -6054,6 +6101,7 @@ static void gen_opcode (unsigned int opcode) fill_prefetch_next_t(); break; case i_CMP: + disable_noflags = 1; genamodedual(curi, curi->smode, "srcreg", curi->size, "src", 1, 0, curi->dmode, "dstreg", curi->size, "dst", 1, 0); @@ -6066,6 +6114,7 @@ static void gen_opcode (unsigned int opcode) } break; case i_CMPA: + disable_noflags = 1; genamodedual(curi, curi->smode, "srcreg", curi->size, "src", 1, 0, curi->dmode, "dstreg", sz_long, "dst", 1, 0); @@ -6525,10 +6574,11 @@ static void gen_opcode (unsigned int opcode) tail_ce020_done = true; break; case i_TRAP: + exception_oldpc(); genamode(curi, curi->smode, "srcreg", curi->size, "src", 1, 0, 0); gen_set_fault_pc (false, true); sync_m68k_pc(); - out("Exception_cpu(src + 32);\n"); + exception_cpu("src + 32"); write_return_cycles_noadd(0); did_prefetch = -1; ipl_fetched = -1; @@ -6693,7 +6743,7 @@ static void gen_opcode (unsigned int opcode) out("SET_NFLG(((uae_s16)format) < 0); \n"); out("SET_ZFLG(format == 0);\n"); out("SET_VFLG(0);\n"); - out("Exception_cpu(14);\n"); + exception_cpu("14"); write_return_cycles(0); out("}\n"); @@ -6785,18 +6835,18 @@ static void gen_opcode (unsigned int opcode) out("SET_NFLG(((uae_s16)format) < 0); \n"); out("SET_ZFLG(format == 0);\n"); out("SET_VFLG(0);\n"); - out("Exception_cpu(14);\n"); + exception_cpu("14"); write_return_cycles(0); } else if (cpu_level == 0) { - out("Exception_cpu(14);\n"); + exception_cpu("14"); write_return_cycles(0); } else if (cpu_level == 3) { // 68030: trace bits are cleared out("regs.t1 = regs.t0 = 0;\n"); - out("Exception_cpu(14);\n"); + exception_cpu("14"); write_return_cycles(0); } else { - out("Exception_cpu(14);\n"); + exception_cpu("14"); write_return_cycles(0); } out("}\n"); @@ -7006,6 +7056,7 @@ static void gen_opcode (unsigned int opcode) } break; case i_TRAPV: + exception_oldpc(); sync_m68k_pc(); if (cpu_level == 0) { // 68000 TRAPV is really weird @@ -7031,14 +7082,14 @@ static void gen_opcode (unsigned int opcode) // stacked opcode is TRAPV out("regs.ir = opcode_v;\n"); } - out("Exception_cpu(7);\n"); + exception_cpu("7"); write_return_cycles(0); out("}\n"); } else if (cpu_level == 1) { push_ins_cnt(); out("if (GET_VFLG()) {\n"); addcycles000(2); - out("Exception_cpu(7);\n"); + exception_cpu("7"); write_return_cycles(0); out("}\n"); pop_ins_cnt(); @@ -7046,7 +7097,7 @@ static void gen_opcode (unsigned int opcode) } else { fill_prefetch_next(); out("if (GET_VFLG()) {\n"); - out("Exception_cpu(7);\n"); + exception_cpu("7"); write_return_cycles(0); out("}\n"); } @@ -7588,7 +7639,7 @@ bccl_not68020: out("if (src) {\n"); if (using_ce) { out("loop_mode_table[regs.ird](regs.ird);\n"); - } else { + } else if (!using_nocycles) { out("count_cycles += loop_mode_table[regs.ird](regs.ird);\n"); } @@ -7724,6 +7775,7 @@ bccl_not68020: next_level_000(); break; case i_DIVU: + exception_oldpc(); tail_ce020_done = true; genamodedual(curi, curi->smode, "srcreg", sz_word, "src", 1, 0, @@ -7733,7 +7785,7 @@ bccl_not68020: out("divbyzero_special(0, dst);\n"); incpc("%d", m68k_pc_offset); addcycles000(4); - out("Exception_cpu(5);\n"); + exception_cpu("5"); write_return_cycles(0); out("}\n"); pop_ins_cnt(); @@ -7765,6 +7817,7 @@ bccl_not68020: next_level_020_to_010(); break; case i_DIVS: + exception_oldpc(); tail_ce020_done = true; genamodedual(curi, curi->smode, "srcreg", sz_word, "src", 1, 0, @@ -7774,7 +7827,7 @@ bccl_not68020: out("divbyzero_special(1, dst);\n"); incpc("%d", m68k_pc_offset); addcycles000(4); - out("Exception_cpu(5);\n"); + exception_cpu("5"); write_return_cycles(0); out("}\n"); pop_ins_cnt(); @@ -7867,25 +7920,29 @@ bccl_not68020: next_level_020_to_010(); break; case i_CHK: + disable_noflags = 1; + exception_oldpc(); genamode(curi, curi->smode, "srcreg", curi->size, "src", 1, 0, 0); genamode(curi, curi->dmode, "dstreg", curi->size, "dst", 1, 0, 0); sync_m68k_pc(); addcycles000(4); out("if (dst > src) {\n"); out("setchkundefinedflags(src, dst, %d);\n", curi->size); - out("Exception_cpu(6);\n"); + exception_cpu("6"); write_return_cycles(0); out("}\n"); addcycles000(2); out("if ((uae_s32)dst < 0) {\n"); out("setchkundefinedflags(src, dst, %d);\n", curi->size); - out("Exception_cpu(6);\n"); + exception_cpu("6"); write_return_cycles(0); out("}\n"); out("setchkundefinedflags(src, dst, %d);\n", curi->size); fill_prefetch_next_t(); break; case i_CHK2: + disable_noflags = 1; + exception_oldpc(); genamode(curi, curi->smode, "srcreg", curi->size, "extra", 1, 0, 0); genamode(curi, curi->dmode, "dstreg", curi->size, "dst", 2, 0, 0); fill_prefetch_0(); @@ -7912,11 +7969,11 @@ bccl_not68020: out("if(upper == reg || lower == reg) {\n"); out("SET_ZFLG(1);\n"); out("}else{\n"); - out("if (lower <= upper && (reg < lower || reg > upper)) SET_CFLG(1);\n"); - out("if (lower > upper && reg > upper && reg < lower) SET_CFLG(1);\n"); + out("if (lower <= upper && (reg < lower || reg > upper)) SET_ALWAYS_CFLG(1);\n"); + out("if (lower > upper && reg > upper && reg < lower) SET_ALWAYS_CFLG(1);\n"); out("}\n"); out("if ((extra & 0x800) && GET_CFLG()) {\n"); - out("Exception_cpu(6);\n"); + exception_cpu("6"); write_return_cycles(0); out("}\n"); break; @@ -8399,6 +8456,7 @@ bccl_not68020: break; case i_CAS: { + disable_noflags = 1; genamode(curi, curi->smode, "srcreg", curi->size, "src", 1, 0, GF_LRMW); genamode(curi, curi->dmode, "dstreg", curi->size, "dst", 1, 0, GF_LRMW); if (cpu_level == 5 && curi->size > 0) { @@ -8439,6 +8497,7 @@ bccl_not68020: } break; case i_CAS2: + disable_noflags = 1; genamode(curi, curi->smode, "srcreg", curi->size, "extra", 1, 0, GF_LRMW); out("uae_u32 rn1 = regs.regs[(extra >> 28) & 15];\n"); out("uae_u32 rn2 = regs.regs[(extra >> 12) & 15];\n"); @@ -8555,20 +8614,22 @@ bccl_not68020: did_prefetch = -1; break; case i_TRAPcc: + exception_oldpc(); if (curi->smode != am_unknown && curi->smode != am_illg) genamode(curi, curi->smode, "srcreg", curi->size, "dummy", 1, 0, 0); fill_prefetch_0(); sync_m68k_pc(); out("if (cctrue(%d)) {\n", curi->cc); - out("Exception_cpu(7);\n"); + exception_cpu("7"); write_return_cycles(0); out("}\n"); break; case i_DIVL: + out("uaecptr oldpc = %s;\n", getpc); genamode(curi, curi->smode, "srcreg", curi->size, "extra", 1, 0, 0); genamode(curi, curi->dmode, "dstreg", curi->size, "dst", 1, 0, 0); sync_m68k_pc(); - out("int e = m68k_divl(opcode, dst, extra);\n"); + out("int e = m68k_divl(opcode, dst, extra, oldpc);\n"); out("if (e <= 0) {\n"); if (mmufixupcnt) { out("if (e < 0) {\n"); @@ -8631,7 +8692,7 @@ bccl_not68020: out("dsta += offset >> 3;\n"); out("tmp = %s(dsta, bdata, offset, width);\n", getb); } - out("SET_NFLG_ALWAYS (((uae_s32)tmp) < 0 ? 1 : 0);\n"); + out("SET_ALWAYS_NFLG(((uae_s32)tmp) < 0 ? 1 : 0);\n"); if (curi->mnemo == i_BFEXTS) out("tmp = (uae_s32)tmp >> (32 - width);\n"); else @@ -8661,7 +8722,7 @@ bccl_not68020: case i_BFINS: out("tmp = m68k_dreg(regs, (extra >> 12) & 7);\n"); out("tmp = tmp & (0xffffffffu >> (32 - width));\n"); - out("SET_NFLG(tmp & (1 << (width - 1)) ? 1 : 0);\n"); + out("SET_ALWAYS_NFLG(tmp & (1 << (width - 1)) ? 1 : 0);\n"); out("SET_ZFLG(tmp == 0);\n"); break; default: @@ -8774,6 +8835,7 @@ bccl_not68020: fpulimit(); genamode(curi, curi->smode, "srcreg", curi->size, "extra", 1, 0, 0); sync_m68k_pc(); + swap_opcode(); out("fpuop_arithmetic(opcode, extra);\n"); if (using_prefetch || using_prefetch_020) { out("if (regs.fp_exception) {\n"); @@ -8785,6 +8847,7 @@ bccl_not68020: fpulimit(); genamode(curi, curi->smode, "srcreg", curi->size, "extra", 1, 0, 0); sync_m68k_pc(); + swap_opcode(); out("fpuop_dbcc (opcode, extra);\n"); if (using_prefetch || using_prefetch_020) { out("if (regs.fp_exception) {\n"); @@ -8806,6 +8869,7 @@ bccl_not68020: fpulimit(); genamode(curi, curi->smode, "srcreg", curi->size, "extra", 1, 0, 0); sync_m68k_pc(); + swap_opcode(); out("fpuop_scc (opcode, extra);\n"); if (using_prefetch || using_prefetch_020) { out("if (regs.fp_exception) {\n"); @@ -8820,6 +8884,7 @@ bccl_not68020: if (curi->smode != am_unknown && curi->smode != am_illg) genamode(curi, curi->smode, "srcreg", curi->size, "dummy", 1, 0, 0); sync_m68k_pc(); + swap_opcode(); out("fpuop_trapcc (opcode, oldpc, extra);\n"); if (using_prefetch || using_prefetch_020) { out("if (regs.fp_exception) {\n"); @@ -8833,6 +8898,7 @@ bccl_not68020: out("uaecptr pc = %s;\n", getpc); genamode(curi, curi->dmode, "srcreg", curi->size, "extra", 1, 0, 0); sync_m68k_pc(); + swap_opcode(); out("fpuop_bcc (opcode, pc,extra);\n"); if (using_prefetch || using_prefetch_020) { out("if (regs.fp_exception) {\n"); @@ -8853,6 +8919,7 @@ bccl_not68020: case i_FSAVE: fpulimit(); sync_m68k_pc(); + swap_opcode(); out("fpuop_save (opcode);\n"); if (using_prefetch || using_prefetch_020) { out("if (regs.fp_exception) {\n"); @@ -8863,6 +8930,7 @@ bccl_not68020: case i_FRESTORE: fpulimit(); sync_m68k_pc(); + swap_opcode(); out("fpuop_restore (opcode);\n"); if (using_prefetch || using_prefetch_020) { out("if (regs.fp_exception) {\n"); @@ -9016,7 +9084,14 @@ end: } } -static void generate_includes (FILE * f, int id) +static void generate_macros(FILE *f) +{ + fprintf(f, + "#define SET_ALWAYS_CFLG(x) SET_CFLG(x)\n" + "#define SET_ALWAYS_NFLG(x) SET_NFLG(x)\n"); +} + +static void generate_includes (FILE *f, int id) { fprintf(f, "#include \"sysconfig.h\"\n"); fprintf(f, "#include \"sysdeps.h\"\n"); @@ -9031,13 +9106,7 @@ static void generate_includes (FILE * f, int id) fprintf(f, "#include \"cpummu.h\"\n"); else if (id == 32 || id == 34 || id == 35) fprintf(f, "#include \"cpummu030.h\"\n"); - - fprintf(f, "#define CPUFUNC(x) x##_ff\n" - "#define SET_CFLG_ALWAYS(x) SET_CFLG(x)\n" - "#define SET_NFLG_ALWAYS(x) SET_NFLG(x)\n" - "#ifdef NOFLAGS\n" - "#include \"noflags.h\"\n" - "#endif\n"); + generate_macros(f); } static char *decodeEA (amodes mode, wordsizes size) @@ -9180,14 +9249,63 @@ struct cputbl_tmp }; static struct cputbl_tmp cputbltmp[65536]; +static const char *remove_nf[] = { + "SET_ZFLG", + "SET_NFLG", + "SET_VFLG", + "SET_CFLG", + "SET_XFLG", + "COPY_CARRY", + "CLEAR_CZNV", + NULL +}; + +static void remove_func(const char *fs, char *p) +{ + for (;;) { + const char *f1 = strstr(p, fs); + if (!f1) + break; + const char *f2 = strchr(f1, ';'); + if (!f2) { + abort(); + } + while (f1 > p && (f1[-1] == '\t' || f1[-1] == ' ')) { + f1--; + } + f2++; + while (*f2 == '\n' || *f2 == '\r') { + f2++; + } + if (f1[1] == '\n') { + f1++; + } + memmove(p + (f1 - p), f2, strlen(f2) + 1); + } +} + +static void convert_to_noflags(char *p) +{ + for (int i = 0; remove_nf[i]; i++) { + remove_func(remove_nf[i], p); + } + const char *f1 = strstr(p, "_ff("); + if (!f1) { + abort(); + } + p[f1 - p + 1] = 'n'; +} + static void generate_one_opcode (int rp, const char *extra) { int idx; uae_u16 smsk, dmsk; unsigned int opcode = opcode_map[rp]; int i68000 = table68k[opcode].clev > 0; + int have_realopcode = 0; brace_level = 0; + disable_noflags = 0; if (table68k[opcode].mnemo == i_ILLG || table68k[opcode].clev > cpu_level) @@ -9206,10 +9324,10 @@ static void generate_one_opcode (int rp, const char *extra) if (opcode_next_clev[rp] != cpu_level) { char *name = ua (lookuptab[idx].name); if (generate_stbl) - fprintf(stblfile, "{ %sCPUFUNC(op_%04x_%d%s), 0x%04x, %d, { %d, %d }, %d }, /* %s */\n", - (using_ce || using_ce020) ? "(cpuop_func*)" : "", - opcode, opcode_last_postfix[rp], - extra, opcode, + fprintf(stblfile, "{ %sop_%04x_%d%s_ff, %sop_%04x_%d%s_ff, 0x%04x, %d, { %d, %d }, %d }, /* %s */\n", + (using_ce || using_ce020) ? "(cpuop_func*)" : "", opcode, opcode_last_postfix[rp], extra, + (using_ce || using_ce020) ? "(cpuop_func*)" : "", opcode, opcode_last_postfix[rp], extra, + opcode, cputbltmp[opcode].length, cputbltmp[opcode].disp020[0], cputbltmp[opcode].disp020[1], cputbltmp[opcode].branch, name); xfree (name); return; @@ -9221,8 +9339,8 @@ static void generate_one_opcode (int rp, const char *extra) out("/* %s */\n", outopcode (opcode)); if (i68000) out("#ifndef CPUEMU_68000_ONLY\n"); - out("%s REGPARAM2 CPUFUNC(op_%04x_%d%s)(uae_u32 opcode)\n{\n", (using_ce || using_ce020) ? "void" : "uae_u32", opcode, postfix, extra); - if (using_simple_cycles || do_always_dynamic_cycles) + out("%s REGPARAM2 op_%04x_%d%s_ff(uae_u32 opcode)\n{\n", (using_ce || using_ce020) ? "void" : "uae_u32", opcode, postfix, extra); + if ((using_simple_cycles || do_always_dynamic_cycles) && !using_nocycles) out("int count_cycles = 0;\n"); switch (table68k[opcode].stype) { @@ -9253,10 +9371,11 @@ static void generate_one_opcode (int rp, const char *extra) char source[100]; int pos = table68k[opcode].spos; + real_opcode(&have_realopcode); if (pos) - sprintf(source, "((opcode >> %d) & %d)", pos, smsk); + sprintf(source, "((real_opcode >> %d) & %d)", pos, smsk); else - sprintf(source, "(opcode & %d)", smsk); + sprintf(source, "(real_opcode & %d)", smsk); if (table68k[opcode].stype == 3) out("uae_u32 srcreg = imm8_table[%s];\n", source); @@ -9279,11 +9398,12 @@ static void generate_one_opcode (int rp, const char *extra) out("uae_u32 dstreg = %d;\n", (int) table68k[opcode].dreg); } else { int pos = table68k[opcode].dpos; + real_opcode(&have_realopcode); if (pos) - out("uae_u32 dstreg = (opcode >> %d) & %d;\n", + out("uae_u32 dstreg = (real_opcode >> %d) & %d;\n", pos, dmsk); else - out("uae_u32 dstreg = opcode & %d;\n", dmsk); + out("uae_u32 dstreg = real_opcode & %d;\n", dmsk); } } count_readw = count_readl = count_writew = count_writel = count_ncycles = count_cycles = 0; @@ -9318,13 +9438,22 @@ static void generate_one_opcode (int rp, const char *extra) printf("%s", outbuffer); + int nfgenerated = 0; + // generate noflags variant if needed + if (using_noflags && table68k[opcode].flagdead != 0 && !disable_noflags) { + convert_to_noflags(outbuffer); + printf("%s", outbuffer); + nfgenerated = 1; + } + if (generate_stbl) { char *name = ua (lookuptab[idx].name); if (i68000) fprintf(stblfile, "#ifndef CPUEMU_68000_ONLY\n"); - fprintf(stblfile, "{ %sCPUFUNC(op_%04x_%d%s), 0x%04x, %d, { %d, %d }, %d }, /* %s */\n", - (using_ce || using_ce020) ? "(cpuop_func*)" : "", - opcode, postfix, extra, opcode, + fprintf(stblfile, "{ %sop_%04x_%d%s_ff, %sop_%04x_%d%s_%s, 0x%04x, %d, { %d, %d }, %d }, /* %s */\n", + (using_ce || using_ce020) ? "(cpuop_func*)" : "", opcode, postfix, extra, + (using_ce || using_ce020) ? "(cpuop_func*)" : "", opcode, postfix, extra, nfgenerated ? "nf" : "ff", + opcode, cputbltmp[opcode].length, cputbltmp[opcode].disp020[0], cputbltmp[opcode].disp020[1], cputbltmp[opcode].branch, name); if (i68000) fprintf(stblfile, "#endif\n"); @@ -9384,6 +9513,7 @@ static void generate_cpu_test(int mode) if (freopen(fname, "wb", stdout) == NULL) { abort(); } + generate_macros(stdout); using_exception_3 = 1; using_bus_error = 1; @@ -9399,6 +9529,7 @@ static void generate_cpu_test(int mode) using_simple_cycles = 0; using_indirect = 1; cpu_generic = false; + need_exception_oldpc = 0; cpu_level = 0; using_prefetch = 1; @@ -9491,6 +9622,9 @@ static void generate_cpu (int id, int mode) using_indirect = 0; cpu_generic = false; need_special_fixup = 0; + need_exception_oldpc = 0; + using_get_word_unswapped = 0; + using_noflags = 0; if (id == 11 || id == 12) { // 11 = 68010 prefetch, 12 = 68000 prefetch cpu_level = id == 11 ? 1 : 0; @@ -9601,16 +9735,28 @@ static void generate_cpu (int id, int mode) } else if (id >= 40 && id < 46) { cpu_level = 5 - (id - 40); // "generic" + direct cpu_generic = true; + need_exception_oldpc = 1; if (id == 40) { read_counts(); for (rp = 0; rp < nr_cpuop_funcs; rp++) opcode_next_clev[rp] = cpu_level; } using_indirect = -1; + using_noflags = 1; + using_nocycles = 1; +#ifdef HAVE_GET_WORD_UNSWAPPED + using_get_word_unswapped = 1; +#endif } else if (id >= 50 && id < 56) { cpu_level = 5 - (id - 50); // "generic" + indirect cpu_generic = true; need_special_fixup = 1; + need_exception_oldpc = 1; + using_noflags = 1; + using_nocycles = 1; +#ifdef HAVE_GET_WORD_UNSWAPPED + using_get_word_unswapped = 1; +#endif if (id == 50) { read_counts(); for (rp = 0; rp < nr_cpuop_funcs; rp++) @@ -9626,7 +9772,7 @@ static void generate_cpu (int id, int mode) if (generate_stbl) { if ((id > 0 && id < 6) || (id >= 20 && id < 40) || (id > 40 && id < 46) || (id > 50 && id < 56)) fprintf(stblfile, "#ifndef CPUEMU_68000_ONLY\n"); - fprintf(stblfile, "const struct cputbl CPUFUNC(op_smalltbl_%d%s)[] = {\n", postfix, extra); + fprintf(stblfile, "const struct cputbl op_smalltbl_%d%s[] = {\n", postfix, extra); } generate_func (extra); if (generate_stbl) { @@ -9640,8 +9786,7 @@ static void generate_cpu (int id, int mode) int main(int argc, char *argv[]) { - read_table68k(); - do_merges(); + init_table68k(); opcode_map = xmalloc (int, nr_cpuop_funcs); opcode_last_postfix = xmalloc (int, nr_cpuop_funcs); diff --git a/include/debug.h b/include/debug.h index 92515ce3..284bae69 100644 --- a/include/debug.h +++ b/include/debug.h @@ -12,6 +12,13 @@ #include "uae/types.h" +#ifndef D +#define D +#endif +#ifndef bug +#define bug write_log +#endif + #ifdef DEBUGGER #define MAX_HIST 500 diff --git a/include/newcpu.h b/include/newcpu.h index 3c818a9e..355fb132 100644 --- a/include/newcpu.h +++ b/include/newcpu.h @@ -58,11 +58,13 @@ typedef uae_u32 REGPARAM3 cpuop_func (uae_u32) REGPARAM; typedef void REGPARAM3 cpuop_func_ce (uae_u32) REGPARAM; struct cputbl { - cpuop_func *handler; + cpuop_func *handler_ff; + cpuop_func *handler_nf; uae_u16 opcode; uae_s8 length; uae_s8 disp020[2]; uae_s8 branch; + uae_u16 specific; }; #ifdef JIT @@ -193,7 +195,6 @@ struct regstruct flagtype t0; flagtype s; flagtype m; - flagtype x; flagtype stopped; int halted; int exception; @@ -328,6 +329,13 @@ STATIC_INLINE void unset_special (uae_u32 x) #define m68k_dreg(r,num) ((r).regs[(num)]) #define m68k_areg(r,num) (((r).regs + 8)[(num)]) +// JIT only +#ifdef HAVE_GET_WORD_UNSWAPPED + #define GET_OPCODE (do_get_mem_word_unswapped((uae_u16*)(pc + pc_offset))); +#else + #define GET_OPCODE (do_get_mem_word((uae_u16*)(pc + pc_offset))); +#endif + extern uae_u32(*x_prefetch)(int); extern uae_u32(*x_get_byte)(uaecptr addr); extern uae_u32(*x_get_word)(uaecptr addr); @@ -672,6 +680,7 @@ extern void REGPARAM3 MakeFromSR_T0(void) REGPARAM; extern void REGPARAM3 MakeFromSR_intmask(uae_u16 oldsr, uae_u16 newsr) REGPARAM; extern void REGPARAM3 Exception (int) REGPARAM; extern void REGPARAM3 Exception_cpu(int) REGPARAM; +extern void REGPARAM3 Exception_cpu_oldpc(int, uaecptr) REGPARAM; extern void REGPARAM3 ExceptionL (int, uaecptr) REGPARAM; extern void NMI (void); extern void NMI_delayed (void); @@ -680,7 +689,7 @@ extern void doint (void); extern void dump_counts (void); extern int m68k_move2c (int, uae_u32 *); extern int m68k_movec2 (int, uae_u32 *); -extern int m68k_divl (uae_u32, uae_u32, uae_u16); +extern int m68k_divl (uae_u32, uae_u32, uae_u16, uaecptr); extern int m68k_mull (uae_u32, uae_u32, uae_u16); extern void init_m68k (void); extern void m68k_go (int); @@ -764,50 +773,49 @@ extern void fill_prefetch_030(void); #define CPU_OP_NAME(a) op ## a /* 68060 */ -extern const struct cputbl op_smalltbl_0_ff[]; -extern const struct cputbl op_smalltbl_40_ff[]; -extern const struct cputbl op_smalltbl_50_ff[]; -extern const struct cputbl op_smalltbl_24_ff[]; // CE -extern const struct cputbl op_smalltbl_33_ff[]; // MMU +extern const struct cputbl op_smalltbl_0[]; +extern const struct cputbl op_smalltbl_40[]; +extern const struct cputbl op_smalltbl_50[]; +extern const struct cputbl op_smalltbl_24[]; // CE +extern const struct cputbl op_smalltbl_33[]; // MMU /* 68040 */ -extern const struct cputbl op_smalltbl_1_ff[]; -extern const struct cputbl op_smalltbl_41_ff[]; -extern const struct cputbl op_smalltbl_51_ff[]; -extern const struct cputbl op_smalltbl_25_ff[]; // CE -extern const struct cputbl op_smalltbl_31_ff[]; // MMU +extern const struct cputbl op_smalltbl_1[]; +extern const struct cputbl op_smalltbl_41[]; +extern const struct cputbl op_smalltbl_51[]; +extern const struct cputbl op_smalltbl_25[]; // CE +extern const struct cputbl op_smalltbl_31[]; // MMU /* 68030 */ -extern const struct cputbl op_smalltbl_2_ff[]; -extern const struct cputbl op_smalltbl_42_ff[]; -extern const struct cputbl op_smalltbl_52_ff[]; -extern const struct cputbl op_smalltbl_22_ff[]; // prefetch -extern const struct cputbl op_smalltbl_23_ff[]; // CE -extern const struct cputbl op_smalltbl_32_ff[]; // MMU -extern const struct cputbl op_smalltbl_34_ff[]; // MMU + cache -extern const struct cputbl op_smalltbl_35_ff[]; // MMU + CE + cache +extern const struct cputbl op_smalltbl_2[]; +extern const struct cputbl op_smalltbl_42[]; +extern const struct cputbl op_smalltbl_52[]; +extern const struct cputbl op_smalltbl_22[]; // prefetch +extern const struct cputbl op_smalltbl_23[]; // CE +extern const struct cputbl op_smalltbl_32[]; // MMU +extern const struct cputbl op_smalltbl_34[]; // MMU + cache +extern const struct cputbl op_smalltbl_35[]; // MMU + CE + cache /* 68020 */ -extern const struct cputbl op_smalltbl_3_ff[]; -extern const struct cputbl op_smalltbl_43_ff[]; -extern const struct cputbl op_smalltbl_53_ff[]; -extern const struct cputbl op_smalltbl_20_ff[]; // prefetch -extern const struct cputbl op_smalltbl_21_ff[]; // CE +extern const struct cputbl op_smalltbl_3[]; +extern const struct cputbl op_smalltbl_43[]; +extern const struct cputbl op_smalltbl_53[]; +extern const struct cputbl op_smalltbl_20[]; // prefetch +extern const struct cputbl op_smalltbl_21[]; // CE /* 68010 */ -extern const struct cputbl op_smalltbl_4_ff[]; -extern const struct cputbl op_smalltbl_44_ff[]; -extern const struct cputbl op_smalltbl_54_ff[]; -extern const struct cputbl op_smalltbl_11_ff[]; // prefetch -extern const struct cputbl op_smalltbl_13_ff[]; // CE +extern const struct cputbl op_smalltbl_4[]; +extern const struct cputbl op_smalltbl_44[]; +extern const struct cputbl op_smalltbl_54[]; +extern const struct cputbl op_smalltbl_11[]; // prefetch +extern const struct cputbl op_smalltbl_13[]; // CE /* 68000 */ -extern const struct cputbl op_smalltbl_5_ff[]; -extern const struct cputbl op_smalltbl_45_ff[]; -extern const struct cputbl op_smalltbl_55_ff[]; -extern const struct cputbl op_smalltbl_12_ff[]; // prefetch -extern const struct cputbl op_smalltbl_14_ff[]; // CE +extern const struct cputbl op_smalltbl_5[]; +extern const struct cputbl op_smalltbl_45[]; +extern const struct cputbl op_smalltbl_55[]; +extern const struct cputbl op_smalltbl_12[]; // prefetch +extern const struct cputbl op_smalltbl_14[]; // CE extern cpuop_func *cpufunctbl[65536] ASM_SYM_FOR_FUNC ("cpufunctbl"); #ifdef JIT -extern void flush_icache(int); -extern void flush_icache_hard(int); +extern void (*flush_icache)(int); extern void compemu_reset(void); #else #define flush_icache(int) do {} while (0) diff --git a/include/readcpu.h b/include/readcpu.h index da779870..5a13bcc3 100644 --- a/include/readcpu.h +++ b/include/readcpu.h @@ -63,9 +63,20 @@ ENUMDECL { fu_used, fu_unused, fu_maybecc, fu_unknown, fu_isjmp } ENUMNAME (flaguse); +ENUMDECL { + fl_normal = 0, + fl_branch = 1, + fl_jump = 2, + fl_return = 3, + fl_trap = 4, + fl_const_jump = 8, + /* Instructions that can trap don't mark the end of a block */ + fl_end_block = 3 +} ENUMNAME (cflow_t); + ENUMDECL { bit0, bit1, bitc, bitC, bitf, biti, bitI, bitj, bitJ, bitk, bitK, - bits, bitS, bitd, bitD, bitr, bitR, bitz, bitp, lastbit + bits, bitS, bitd, bitD, bitr, bitR, bitz, bitE, bitp, lastbit } ENUMNAME (bitvals); struct instr_def { @@ -77,9 +88,10 @@ struct instr_def { int unimpcpulevel; int plevel; struct { - unsigned int flaguse:3; - unsigned int flagset:3; + unsigned int flaguse:3; + unsigned int flagset:3; } flaginfo[5]; + uae_u8 cflow; uae_u8 sduse; const TCHAR *opcstr; // 68020/030 timing @@ -109,14 +121,15 @@ extern struct instr { unsigned int duse:1; unsigned int ccuse:1; unsigned int clev:3, unimpclev:3; - unsigned int isjmp:1; + unsigned int cflow:3; unsigned int unused2:1; char head, tail, clocks, fetchmode; } *table68k; -extern void read_table68k (void); -extern void do_merges (void); -extern int get_no_mismatches (void); +extern void init_table68k(void); +extern void exit_table68k(void); + +extern int get_no_mismatches(void); extern int nr_cpuop_funcs; extern bool opcode_loop_mode(uae_u16 opcode); diff --git a/include/sysdeps.h b/include/sysdeps.h index 94d4c31f..835e6bbd 100644 --- a/include/sysdeps.h +++ b/include/sysdeps.h @@ -43,8 +43,11 @@ using namespace std; #if defined(__x86_64__) || defined(_M_AMD64) #define CPU_x86_64 1 #define CPU_64_BIT 1 +#define X86_64_ASSEMBLY 1 #elif defined(__i386__) || defined(_M_IX86) #define CPU_i386 1 +#define X86_ASSEMBLY 1 +#define SAHF_SETO_PROFITABLE #elif defined(__arm__) || defined(_M_ARM) #define CPU_arm 1 #elif defined(__powerpc__) || defined(_M_PPC) @@ -412,7 +415,8 @@ extern void mallocemu_free (void *ptr); #endif #ifdef X86_ASSEMBLY -#define ASM_SYM_FOR_FUNC(a) __asm__(a) +//#define ASM_SYM_FOR_FUNC(a) __asm__(a) +#define ASM_SYM_FOR_FUNC(a) #else #define ASM_SYM_FOR_FUNC(a) #endif diff --git a/include/uae/memory.h b/include/uae/memory.h new file mode 100644 index 00000000..1270eae8 --- /dev/null +++ b/include/uae/memory.h @@ -0,0 +1,2 @@ +#include "options.h" +#include "../memory.h" diff --git a/jit/codegen_x86.cpp b/jit/codegen_x86.cpp index 8bd53e85..1e178629 100644 --- a/jit/codegen_x86.cpp +++ b/jit/codegen_x86.cpp @@ -196,11 +196,6 @@ static const uae_u8 need_to_preserve[]={0,0,0,1,0,1,1,1}; #define CLOBBER_BT clobber_flags() #define CLOBBER_BSF clobber_flags() -/* The older code generator is now deprecated. */ -#define USE_NEW_RTASM 1 - -#if USE_NEW_RTASM - #if defined(CPU_x86_64) #define X86_TARGET_64BIT 1 /* The address override prefix causes a 5 cycles penalty on Intel Core @@ -272,6 +267,7 @@ static inline void x86_64_prefix( #define compemu_raw_jmp_r(a) raw_jmp_r(a) #define compemu_raw_jnz(a) raw_jnz(a) #define compemu_raw_jz_b_oponly() raw_jz_b_oponly() +#define compemu_raw_jnz_b_oponly() raw_jnz_b_oponly() #define compemu_raw_lea_l_brr(a,b,c) raw_lea_l_brr(a,b,c) #define compemu_raw_lea_l_brr_indexed(a,b,c,d,e) raw_lea_l_brr_indexed(a,b,c,d,e) #define compemu_raw_mov_b_mr(a,b) raw_mov_b_mr(a,b) @@ -300,7 +296,6 @@ LOWFUNC(NONE,WRITE,1,raw_push_l_r,(R4 r)) PUSHLr(r); #endif } -LENDFUNC(NONE,WRITE,1,raw_push_l_r,(R4 r)) LOWFUNC(NONE,READ,1,raw_pop_l_r,(R4 r)) { @@ -310,7 +305,6 @@ LOWFUNC(NONE,READ,1,raw_pop_l_r,(R4 r)) POPLr(r); #endif } -LENDFUNC(NONE,READ,1,raw_pop_l_r,(R4 r)) LOWFUNC(NONE,READ,1,raw_pop_l_m,(MEMW d)) { @@ -320,307 +314,256 @@ LOWFUNC(NONE,READ,1,raw_pop_l_m,(MEMW d)) POPLm(d, X86_NOREG, X86_NOREG, 1); #endif } -LENDFUNC(NONE,READ,1,raw_pop_l_m,(MEMW d)) LOWFUNC(WRITE,NONE,2,raw_bt_l_ri,(R4 r, IMM i)) { BTLir(i, r); } -LENDFUNC(WRITE,NONE,2,raw_bt_l_ri,(R4 r, IMM i)) LOWFUNC(WRITE,NONE,2,raw_bt_l_rr,(R4 r, R4 b)) { BTLrr(b, r); } -LENDFUNC(WRITE,NONE,2,raw_bt_l_rr,(R4 r, R4 b)) LOWFUNC(WRITE,NONE,2,raw_btc_l_ri,(RW4 r, IMM i)) { BTCLir(i, r); } -LENDFUNC(WRITE,NONE,2,raw_btc_l_ri,(RW4 r, IMM i)) LOWFUNC(WRITE,NONE,2,raw_btc_l_rr,(RW4 r, R4 b)) { BTCLrr(b, r); } -LENDFUNC(WRITE,NONE,2,raw_btc_l_rr,(RW4 r, R4 b)) LOWFUNC(WRITE,NONE,2,raw_btr_l_ri,(RW4 r, IMM i)) { BTRLir(i, r); } -LENDFUNC(WRITE,NONE,2,raw_btr_l_ri,(RW4 r, IMM i)) LOWFUNC(WRITE,NONE,2,raw_btr_l_rr,(RW4 r, R4 b)) { BTRLrr(b, r); } -LENDFUNC(WRITE,NONE,2,raw_btr_l_rr,(RW4 r, R4 b)) LOWFUNC(WRITE,NONE,2,raw_bts_l_ri,(RW4 r, IMM i)) { BTSLir(i, r); } -LENDFUNC(WRITE,NONE,2,raw_bts_l_ri,(RW4 r, IMM i)) LOWFUNC(WRITE,NONE,2,raw_bts_l_rr,(RW4 r, R4 b)) { BTSLrr(b, r); } -LENDFUNC(WRITE,NONE,2,raw_bts_l_rr,(RW4 r, R4 b)) LOWFUNC(WRITE,NONE,2,raw_sub_w_ri,(RW2 d, IMM i)) { SUBWir(i, d); } -LENDFUNC(WRITE,NONE,2,raw_sub_w_ri,(RW2 d, IMM i)) LOWFUNC(NONE,READ,2,raw_mov_l_rm,(W4 d, MEMR s)) { ADDR32 MOVLmr(s, X86_NOREG, X86_NOREG, 1, d); } -LENDFUNC(NONE,READ,2,raw_mov_l_rm,(W4 d, MEMR s)) LOWFUNC(NONE,WRITE,2,raw_mov_l_mi,(MEMW d, IMM s)) { ADDR32 MOVLim(s, d, X86_NOREG, X86_NOREG, 1); } -LENDFUNC(NONE,WRITE,2,raw_mov_l_mi,(MEMW d, IMM s)) LOWFUNC(NONE,WRITE,2,raw_mov_w_mi,(MEMW d, IMM s)) { ADDR32 MOVWim(s, d, X86_NOREG, X86_NOREG, 1); } -LENDFUNC(NONE,WRITE,2,raw_mov_w_mi,(MEMW d, IMM s)) LOWFUNC(NONE,WRITE,2,raw_mov_b_mi,(MEMW d, IMM s)) { ADDR32 MOVBim(s, d, X86_NOREG, X86_NOREG, 1); } -LENDFUNC(NONE,WRITE,2,raw_mov_b_mi,(MEMW d, IMM s)) LOWFUNC(WRITE,RMW,2,raw_rol_b_mi,(MEMRW d, IMM i)) { ADDR32 ROLBim(i, d, X86_NOREG, X86_NOREG, 1); } -LENDFUNC(WRITE,RMW,2,raw_rol_b_mi,(MEMRW d, IMM i)) LOWFUNC(WRITE,NONE,2,raw_rol_b_ri,(RW1 r, IMM i)) { ROLBir(i, r); } -LENDFUNC(WRITE,NONE,2,raw_rol_b_ri,(RW1 r, IMM i)) LOWFUNC(WRITE,NONE,2,raw_rol_w_ri,(RW2 r, IMM i)) { ROLWir(i, r); } -LENDFUNC(WRITE,NONE,2,raw_rol_w_ri,(RW2 r, IMM i)) LOWFUNC(WRITE,NONE,2,raw_rol_l_ri,(RW4 r, IMM i)) { ROLLir(i, r); } -LENDFUNC(WRITE,NONE,2,raw_rol_l_ri,(RW4 r, IMM i)) LOWFUNC(WRITE,NONE,2,raw_rol_l_rr,(RW4 d, R1 r)) { ROLLrr(r, d); } -LENDFUNC(WRITE,NONE,2,raw_rol_l_rr,(RW4 d, R1 r)) LOWFUNC(WRITE,NONE,2,raw_rol_w_rr,(RW2 d, R1 r)) { ROLWrr(r, d); } -LENDFUNC(WRITE,NONE,2,raw_rol_w_rr,(RW2 d, R1 r)) LOWFUNC(WRITE,NONE,2,raw_rol_b_rr,(RW1 d, R1 r)) { ROLBrr(r, d); } -LENDFUNC(WRITE,NONE,2,raw_rol_b_rr,(RW1 d, R1 r)) LOWFUNC(WRITE,NONE,2,raw_shll_l_rr,(RW4 d, R1 r)) { SHLLrr(r, d); } -LENDFUNC(WRITE,NONE,2,raw_shll_l_rr,(RW4 d, R1 r)) LOWFUNC(WRITE,NONE,2,raw_shll_w_rr,(RW2 d, R1 r)) { SHLWrr(r, d); } -LENDFUNC(WRITE,NONE,2,raw_shll_w_rr,(RW2 d, R1 r)) LOWFUNC(WRITE,NONE,2,raw_shll_b_rr,(RW1 d, R1 r)) { SHLBrr(r, d); } -LENDFUNC(WRITE,NONE,2,raw_shll_b_rr,(RW1 d, R1 r)) LOWFUNC(WRITE,NONE,2,raw_ror_b_ri,(RW1 r, IMM i)) { RORBir(i, r); } -LENDFUNC(WRITE,NONE,2,raw_ror_b_ri,(RW1 r, IMM i)) LOWFUNC(WRITE,NONE,2,raw_ror_w_ri,(RW2 r, IMM i)) { RORWir(i, r); } -LENDFUNC(WRITE,NONE,2,raw_ror_w_ri,(RW2 r, IMM i)) LOWFUNC(WRITE,READ,2,raw_or_l_rm,(RW4 d, MEMR s)) { ADDR32 ORLmr(s, X86_NOREG, X86_NOREG, 1, d); } -LENDFUNC(WRITE,READ,2,raw_or_l_rm,(RW4 d, MEMR s)) LOWFUNC(WRITE,NONE,2,raw_ror_l_ri,(RW4 r, IMM i)) { RORLir(i, r); } -LENDFUNC(WRITE,NONE,2,raw_ror_l_ri,(RW4 r, IMM i)) LOWFUNC(WRITE,NONE,2,raw_ror_l_rr,(RW4 d, R1 r)) { RORLrr(r, d); } -LENDFUNC(WRITE,NONE,2,raw_ror_l_rr,(RW4 d, R1 r)) LOWFUNC(WRITE,NONE,2,raw_ror_w_rr,(RW2 d, R1 r)) { RORWrr(r, d); } -LENDFUNC(WRITE,NONE,2,raw_ror_w_rr,(RW2 d, R1 r)) LOWFUNC(WRITE,NONE,2,raw_ror_b_rr,(RW1 d, R1 r)) { RORBrr(r, d); } -LENDFUNC(WRITE,NONE,2,raw_ror_b_rr,(RW1 d, R1 r)) LOWFUNC(WRITE,NONE,2,raw_shrl_l_rr,(RW4 d, R1 r)) { SHRLrr(r, d); } -LENDFUNC(WRITE,NONE,2,raw_shrl_l_rr,(RW4 d, R1 r)) LOWFUNC(WRITE,NONE,2,raw_shrl_w_rr,(RW2 d, R1 r)) { SHRWrr(r, d); } -LENDFUNC(WRITE,NONE,2,raw_shrl_w_rr,(RW2 d, R1 r)) LOWFUNC(WRITE,NONE,2,raw_shrl_b_rr,(RW1 d, R1 r)) { SHRBrr(r, d); } -LENDFUNC(WRITE,NONE,2,raw_shrl_b_rr,(RW1 d, R1 r)) LOWFUNC(WRITE,NONE,2,raw_shra_l_rr,(RW4 d, R1 r)) { SARLrr(r, d); } -LENDFUNC(WRITE,NONE,2,raw_shra_l_rr,(RW4 d, R1 r)) LOWFUNC(WRITE,NONE,2,raw_shra_w_rr,(RW2 d, R1 r)) { SARWrr(r, d); } -LENDFUNC(WRITE,NONE,2,raw_shra_w_rr,(RW2 d, R1 r)) LOWFUNC(WRITE,NONE,2,raw_shra_b_rr,(RW1 d, R1 r)) { SARBrr(r, d); } -LENDFUNC(WRITE,NONE,2,raw_shra_b_rr,(RW1 d, R1 r)) LOWFUNC(WRITE,NONE,2,raw_shll_l_ri,(RW4 r, IMM i)) { SHLLir(i, r); } -LENDFUNC(WRITE,NONE,2,raw_shll_l_ri,(RW4 r, IMM i)) LOWFUNC(WRITE,NONE,2,raw_shll_w_ri,(RW2 r, IMM i)) { SHLWir(i, r); } -LENDFUNC(WRITE,NONE,2,raw_shll_w_ri,(RW2 r, IMM i)) LOWFUNC(WRITE,NONE,2,raw_shll_b_ri,(RW1 r, IMM i)) { SHLBir(i, r); } -LENDFUNC(WRITE,NONE,2,raw_shll_b_ri,(RW1 r, IMM i)) LOWFUNC(WRITE,NONE,2,raw_shrl_l_ri,(RW4 r, IMM i)) { SHRLir(i, r); } -LENDFUNC(WRITE,NONE,2,raw_shrl_l_ri,(RW4 r, IMM i)) LOWFUNC(WRITE,NONE,2,raw_shrl_w_ri,(RW2 r, IMM i)) { SHRWir(i, r); } -LENDFUNC(WRITE,NONE,2,raw_shrl_w_ri,(RW2 r, IMM i)) LOWFUNC(WRITE,NONE,2,raw_shrl_b_ri,(RW1 r, IMM i)) { SHRBir(i, r); } -LENDFUNC(WRITE,NONE,2,raw_shrl_b_ri,(RW1 r, IMM i)) LOWFUNC(WRITE,NONE,2,raw_shra_l_ri,(RW4 r, IMM i)) { SARLir(i, r); } -LENDFUNC(WRITE,NONE,2,raw_shra_l_ri,(RW4 r, IMM i)) LOWFUNC(WRITE,NONE,2,raw_shra_w_ri,(RW2 r, IMM i)) { SARWir(i, r); } -LENDFUNC(WRITE,NONE,2,raw_shra_w_ri,(RW2 r, IMM i)) LOWFUNC(WRITE,NONE,2,raw_shra_b_ri,(RW1 r, IMM i)) { SARBir(i, r); } -LENDFUNC(WRITE,NONE,2,raw_shra_b_ri,(RW1 r, IMM i)) LOWFUNC(WRITE,NONE,1,raw_sahf,(R2)) { SAHF(); } -LENDFUNC(WRITE,NONE,1,raw_sahf,(R2 dummy_ah)) LOWFUNC(NONE,NONE,1,raw_cpuid,(R4)) { CPUID(); } -LENDFUNC(NONE,NONE,1,raw_cpuid,(R4 dummy_eax)) LOWFUNC(READ,NONE,1,raw_lahf,(W2)) { LAHF(); } -LENDFUNC(READ,NONE,1,raw_lahf,(W2 dummy_ah)) LOWFUNC(READ,NONE,2,raw_setcc,(W1 d, IMM cc)) { SETCCir(cc, d); } -LENDFUNC(READ,NONE,2,raw_setcc,(W1 d, IMM cc)) LOWFUNC(READ,WRITE,2,raw_setcc_m,(MEMW d, IMM cc)) { ADDR32 SETCCim(cc, d, X86_NOREG, X86_NOREG, 1); } -LENDFUNC(READ,WRITE,2,raw_setcc_m,(MEMW d, IMM cc)) LOWFUNC(READ,NONE,3,raw_cmov_l_rr,(RW4 d, R4 s, IMM cc)) { @@ -633,49 +576,41 @@ LOWFUNC(READ,NONE,3,raw_cmov_l_rr,(RW4 d, R4 s, IMM cc)) *target_p = (uintptr)x86_get_target() - ((uintptr)target_p + 1); } } -LENDFUNC(READ,NONE,3,raw_cmov_l_rr,(RW4 d, R4 s, IMM cc)) LOWFUNC(WRITE,NONE,2,raw_bsf_l_rr,(W4 d, R4 s)) { BSFLrr(s, d); } -LENDFUNC(WRITE,NONE,2,raw_bsf_l_rr,(W4 d, R4 s)) LOWFUNC(NONE,NONE,2,raw_sign_extend_32_rr,(W4 d, R4 s)) { MOVSLQrr(s, d); } -LENDFUNC(NONE,NONE,2,raw_sign_extend_32_rr,(W4 d, R4 s)) LOWFUNC(NONE,NONE,2,raw_sign_extend_16_rr,(W4 d, R2 s)) { MOVSWLrr(s, d); } -LENDFUNC(NONE,NONE,2,raw_sign_extend_16_rr,(W4 d, R2 s)) LOWFUNC(NONE,NONE,2,raw_sign_extend_8_rr,(W4 d, R1 s)) { MOVSBLrr(s, d); } -LENDFUNC(NONE,NONE,2,raw_sign_extend_8_rr,(W4 d, R1 s)) LOWFUNC(NONE,NONE,2,raw_zero_extend_16_rr,(W4 d, R2 s)) { MOVZWLrr(s, d); } -LENDFUNC(NONE,NONE,2,raw_zero_extend_16_rr,(W4 d, R2 s)) LOWFUNC(NONE,NONE,2,raw_zero_extend_8_rr,(W4 d, R1 s)) { MOVZBLrr(s, d); } -LENDFUNC(NONE,NONE,2,raw_zero_extend_8_rr,(W4 d, R1 s)) LOWFUNC(NONE,NONE,2,raw_imul_32_32,(RW4 d, R4 s)) { IMULLrr(s, d); } -LENDFUNC(NONE,NONE,2,raw_imul_32_32,(RW4 d, R4 s)) LOWFUNC(NONE,NONE,2,raw_imul_64_32,(RW4 d, RW4 s)) { @@ -684,7 +619,6 @@ LOWFUNC(NONE,NONE,2,raw_imul_64_32,(RW4 d, RW4 s)) } IMULLr(s); } -LENDFUNC(NONE,NONE,2,raw_imul_64_32,(RW4 d, RW4 s)) LOWFUNC(NONE,NONE,2,raw_mul_64_32,(RW4 d, RW4 s)) { @@ -693,103 +627,86 @@ LOWFUNC(NONE,NONE,2,raw_mul_64_32,(RW4 d, RW4 s)) } MULLr(s); } -LENDFUNC(NONE,NONE,2,raw_mul_64_32,(RW4 d, RW4 s)) LOWFUNC(NONE,NONE,2,raw_mul_32_32,(RW4, R4)) { - abort(); /* %^$&%^$%#^ x86! */ + x86_emit_failure("raw_mul_32_32"); /* %^$&%^$%#^ x86! */ } -LENDFUNC(NONE,NONE,2,raw_mul_32_32,(RW4 d, R4 s)) LOWFUNC(NONE,NONE,2,raw_mov_b_rr,(W1 d, R1 s)) { MOVBrr(s, d); } -LENDFUNC(NONE,NONE,2,raw_mov_b_rr,(W1 d, R1 s)) LOWFUNC(NONE,NONE,2,raw_mov_w_rr,(W2 d, R2 s)) { MOVWrr(s, d); } -LENDFUNC(NONE,NONE,2,raw_mov_w_rr,(W2 d, R2 s)) LOWFUNC(NONE,READ,4,raw_mov_l_rrm_indexed,(W4 d,R4 baser, R4 index, IMM factor)) { ADDR32 MOVLmr(0, baser, index, factor, d); } -LENDFUNC(NONE,READ,4,raw_mov_l_rrm_indexed,(W4 d,R4 baser, R4 index, IMM factor)) LOWFUNC(NONE,READ,4,raw_mov_w_rrm_indexed,(W2 d, R4 baser, R4 index, IMM factor)) { ADDR32 MOVWmr(0, baser, index, factor, d); } -LENDFUNC(NONE,READ,4,raw_mov_w_rrm_indexed,(W2 d, R4 baser, R4 index, IMM factor)) LOWFUNC(NONE,READ,4,raw_mov_b_rrm_indexed,(W1 d, R4 baser, R4 index, IMM factor)) { ADDR32 MOVBmr(0, baser, index, factor, d); } -LENDFUNC(NONE,READ,4,raw_mov_b_rrm_indexed,(W1 d, R4 baser, R4 index, IMM factor)) LOWFUNC(NONE,WRITE,4,raw_mov_l_mrr_indexed,(R4 baser, R4 index, IMM factor, R4 s)) { ADDR32 MOVLrm(s, 0, baser, index, factor); } -LENDFUNC(NONE,WRITE,4,raw_mov_l_mrr_indexed,(R4 baser, R4 index, IMM factor, R4 s)) LOWFUNC(NONE,WRITE,4,raw_mov_w_mrr_indexed,(R4 baser, R4 index, IMM factor, R2 s)) { ADDR32 MOVWrm(s, 0, baser, index, factor); } -LENDFUNC(NONE,WRITE,4,raw_mov_w_mrr_indexed,(R4 baser, R4 index, IMM factor, R2 s)) LOWFUNC(NONE,WRITE,4,raw_mov_b_mrr_indexed,(R4 baser, R4 index, IMM factor, R1 s)) { ADDR32 MOVBrm(s, 0, baser, index, factor); } -LENDFUNC(NONE,WRITE,4,raw_mov_b_mrr_indexed,(R4 baser, R4 index, IMM factor, R1 s)) LOWFUNC(NONE,WRITE,5,raw_mov_l_bmrr_indexed,(IMM base, R4 baser, R4 index, IMM factor, R4 s)) { ADDR32 MOVLrm(s, base, baser, index, factor); } -LENDFUNC(NONE,WRITE,5,raw_mov_l_bmrr_indexed,(IMM base, R4 baser, R4 index, IMM factor, R4 s)) LOWFUNC(NONE,WRITE,5,raw_mov_w_bmrr_indexed,(IMM base, R4 baser, R4 index, IMM factor, R2 s)) { ADDR32 MOVWrm(s, base, baser, index, factor); } -LENDFUNC(NONE,WRITE,5,raw_mov_w_bmrr_indexed,(IMM base, R4 baser, R4 index, IMM factor, R2 s)) LOWFUNC(NONE,WRITE,5,raw_mov_b_bmrr_indexed,(IMM base, R4 baser, R4 index, IMM factor, R1 s)) { ADDR32 MOVBrm(s, base, baser, index, factor); } -LENDFUNC(NONE,WRITE,5,raw_mov_b_bmrr_indexed,(IMM base, R4 baser, R4 index, IMM factor, R1 s)) LOWFUNC(NONE,READ,5,raw_mov_l_brrm_indexed,(W4 d, IMM base, R4 baser, R4 index, IMM factor)) { ADDR32 MOVLmr(base, baser, index, factor, d); } -LENDFUNC(NONE,READ,5,raw_mov_l_brrm_indexed,(W4 d, IMM base, R4 baser, R4 index, IMM factor)) LOWFUNC(NONE,READ,5,raw_mov_w_brrm_indexed,(W2 d, IMM base, R4 baser, R4 index, IMM factor)) { ADDR32 MOVWmr(base, baser, index, factor, d); } -LENDFUNC(NONE,READ,5,raw_mov_w_brrm_indexed,(W2 d, IMM base, R4 baser, R4 index, IMM factor)) LOWFUNC(NONE,READ,5,raw_mov_b_brrm_indexed,(W1 d, IMM base, R4 baser, R4 index, IMM factor)) { ADDR32 MOVBmr(base, baser, index, factor, d); } -LENDFUNC(NONE,READ,5,raw_mov_b_brrm_indexed,(W1 d, IMM base, R4 baser, R4 index, IMM factor)) LOWFUNC(NONE,READ,4,raw_mov_l_rm_indexed,(W4 d, IMM base, R4 index, IMM factor)) { ADDR32 MOVLmr(base, X86_NOREG, index, factor, d); } -LENDFUNC(NONE,READ,4,raw_mov_l_rm_indexed,(W4 d, IMM base, R4 index, IMM factor)) LOWFUNC(NONE,READ,5,raw_cmov_l_rm_indexed,(W4 d, IMM base, R4 index, IMM factor, IMM cond)) { @@ -802,7 +719,6 @@ LOWFUNC(NONE,READ,5,raw_cmov_l_rm_indexed,(W4 d, IMM base, R4 index, IMM factor, *target_p = (uintptr)x86_get_target() - ((uintptr)target_p + 1); } } -LENDFUNC(NONE,READ,5,raw_cmov_l_rm_indexed,(W4 d, IMM base, R4 index, IMM factor, IMM cond)) LOWFUNC(NONE,READ,3,raw_cmov_l_rm,(W4 d, IMM mem, IMM cond)) { @@ -815,2290 +731,423 @@ LOWFUNC(NONE,READ,3,raw_cmov_l_rm,(W4 d, IMM mem, IMM cond)) *target_p = (uintptr)x86_get_target() - ((uintptr)target_p + 1); } } -LENDFUNC(NONE,READ,3,raw_cmov_l_rm,(W4 d, IMM mem, IMM cond)) LOWFUNC(NONE,READ,3,raw_mov_l_rR,(W4 d, R4 s, IMM offset)) { ADDR32 MOVLmr(offset, s, X86_NOREG, 1, d); } -LENDFUNC(NONE,READ,3,raw_mov_l_rR,(W4 d, R4 s, IMM offset)) LOWFUNC(NONE,READ,3,raw_mov_w_rR,(W2 d, R4 s, IMM offset)) { ADDR32 MOVWmr(offset, s, X86_NOREG, 1, d); } -LENDFUNC(NONE,READ,3,raw_mov_w_rR,(W2 d, R4 s, IMM offset)) LOWFUNC(NONE,READ,3,raw_mov_b_rR,(W1 d, R4 s, IMM offset)) { ADDR32 MOVBmr(offset, s, X86_NOREG, 1, d); } -LENDFUNC(NONE,READ,3,raw_mov_b_rR,(W1 d, R4 s, IMM offset)) LOWFUNC(NONE,READ,3,raw_mov_l_brR,(W4 d, R4 s, IMM offset)) { ADDR32 MOVLmr(offset, s, X86_NOREG, 1, d); } -LENDFUNC(NONE,READ,3,raw_mov_l_brR,(W4 d, R4 s, IMM offset)) LOWFUNC(NONE,READ,3,raw_mov_w_brR,(W2 d, R4 s, IMM offset)) { ADDR32 MOVWmr(offset, s, X86_NOREG, 1, d); } -LENDFUNC(NONE,READ,3,raw_mov_w_brR,(W2 d, R4 s, IMM offset)) LOWFUNC(NONE,READ,3,raw_mov_b_brR,(W1 d, R4 s, IMM offset)) { ADDR32 MOVBmr(offset, s, X86_NOREG, 1, d); } -LENDFUNC(NONE,READ,3,raw_mov_b_brR,(W1 d, R4 s, IMM offset)) LOWFUNC(NONE,WRITE,3,raw_mov_l_Ri,(R4 d, IMM i, IMM offset)) { ADDR32 MOVLim(i, offset, d, X86_NOREG, 1); } -LENDFUNC(NONE,WRITE,3,raw_mov_l_Ri,(R4 d, IMM i, IMM offset)) LOWFUNC(NONE,WRITE,3,raw_mov_w_Ri,(R4 d, IMM i, IMM offset)) { ADDR32 MOVWim(i, offset, d, X86_NOREG, 1); } -LENDFUNC(NONE,WRITE,3,raw_mov_w_Ri,(R4 d, IMM i, IMM offset)) LOWFUNC(NONE,WRITE,3,raw_mov_b_Ri,(R4 d, IMM i, IMM offset)) { ADDR32 MOVBim(i, offset, d, X86_NOREG, 1); } -LENDFUNC(NONE,WRITE,3,raw_mov_b_Ri,(R4 d, IMM i, IMM offset)) LOWFUNC(NONE,WRITE,3,raw_mov_l_Rr,(R4 d, R4 s, IMM offset)) { ADDR32 MOVLrm(s, offset, d, X86_NOREG, 1); } -LENDFUNC(NONE,WRITE,3,raw_mov_l_Rr,(R4 d, R4 s, IMM offset)) LOWFUNC(NONE,WRITE,3,raw_mov_w_Rr,(R4 d, R2 s, IMM offset)) { ADDR32 MOVWrm(s, offset, d, X86_NOREG, 1); } -LENDFUNC(NONE,WRITE,3,raw_mov_w_Rr,(R4 d, R2 s, IMM offset)) LOWFUNC(NONE,WRITE,3,raw_mov_b_Rr,(R4 d, R1 s, IMM offset)) { ADDR32 MOVBrm(s, offset, d, X86_NOREG, 1); } -LENDFUNC(NONE,WRITE,3,raw_mov_b_Rr,(R4 d, R1 s, IMM offset)) LOWFUNC(NONE,NONE,3,raw_lea_l_brr,(W4 d, R4 s, IMM offset)) { ADDR32 LEALmr(offset, s, X86_NOREG, 1, d); } -LENDFUNC(NONE,NONE,3,raw_lea_l_brr,(W4 d, R4 s, IMM offset)) LOWFUNC(NONE,NONE,5,raw_lea_l_brr_indexed,(W4 d, R4 s, R4 index, IMM factor, IMM offset)) { ADDR32 LEALmr(offset, s, index, factor, d); } -LENDFUNC(NONE,NONE,5,raw_lea_l_brr_indexed,(W4 d, R4 s, R4 index, IMM factor, IMM offset)) LOWFUNC(NONE,NONE,4,raw_lea_l_rr_indexed,(W4 d, R4 s, R4 index, IMM factor)) { ADDR32 LEALmr(0, s, index, factor, d); } -LENDFUNC(NONE,NONE,4,raw_lea_l_rr_indexed,(W4 d, R4 s, R4 index, IMM factor)) LOWFUNC(NONE,NONE,4,raw_lea_l_r_scaled,(W4 d, R4 index, IMM factor)) { ADDR32 LEALmr(0, X86_NOREG, index, factor, d); } -LENDFUNC(NONE,NONE,4,raw_lea_l_r_scaled,(W4 d, R4 index, IMM factor)) LOWFUNC(NONE,WRITE,3,raw_mov_l_bRr,(R4 d, R4 s, IMM offset)) -{ - ADDR32 MOVLrm(s, offset, d, X86_NOREG, 1); -} -LENDFUNC(NONE,WRITE,3,raw_mov_l_bRr,(R4 d, R4 s, IMM offset)) - -LOWFUNC(NONE,WRITE,3,raw_mov_w_bRr,(R4 d, R2 s, IMM offset)) -{ - ADDR32 MOVWrm(s, offset, d, X86_NOREG, 1); -} -LENDFUNC(NONE,WRITE,3,raw_mov_w_bRr,(R4 d, R2 s, IMM offset)) - -LOWFUNC(NONE,WRITE,3,raw_mov_b_bRr,(R4 d, R1 s, IMM offset)) -{ - ADDR32 MOVBrm(s, offset, d, X86_NOREG, 1); -} -LENDFUNC(NONE,WRITE,3,raw_mov_b_bRr,(R4 d, R1 s, IMM offset)) - -LOWFUNC(NONE,NONE,1,raw_bswap_32,(RW4 r)) -{ - BSWAPLr(r); -} -LENDFUNC(NONE,NONE,1,raw_bswap_32,(RW4 r)) - -LOWFUNC(WRITE,NONE,1,raw_bswap_16,(RW2 r)) -{ - ROLWir(8, r); -} -LENDFUNC(WRITE,NONE,1,raw_bswap_16,(RW2 r)) - -LOWFUNC(NONE,NONE,2,raw_mov_l_rr,(W4 d, R4 s)) -{ - MOVLrr(s, d); -} -LENDFUNC(NONE,NONE,2,raw_mov_l_rr,(W4 d, R4 s)) - -LOWFUNC(NONE,WRITE,2,raw_mov_l_mr,(IMM d, R4 s)) -{ - ADDR32 MOVLrm(s, d, X86_NOREG, X86_NOREG, 1); -} -LENDFUNC(NONE,WRITE,2,raw_mov_l_mr,(IMM d, R4 s)) - -LOWFUNC(NONE,WRITE,2,raw_mov_w_mr,(IMM d, R2 s)) -{ - ADDR32 MOVWrm(s, d, X86_NOREG, X86_NOREG, 1); -} -LENDFUNC(NONE,WRITE,2,raw_mov_w_mr,(IMM d, R2 s)) - -LOWFUNC(NONE,READ,2,raw_mov_w_rm,(W2 d, IMM s)) -{ - ADDR32 MOVWmr(s, X86_NOREG, X86_NOREG, 1, d); -} -LENDFUNC(NONE,READ,2,raw_mov_w_rm,(W2 d, IMM s)) - -LOWFUNC(NONE,WRITE,2,raw_mov_b_mr,(IMM d, R1 s)) -{ - ADDR32 MOVBrm(s, d, X86_NOREG, X86_NOREG, 1); -} -LENDFUNC(NONE,WRITE,2,raw_mov_b_mr,(IMM d, R1 s)) - -LOWFUNC(NONE,READ,2,raw_mov_b_rm,(W1 d, IMM s)) -{ - ADDR32 MOVBmr(s, X86_NOREG, X86_NOREG, 1, d); -} -LENDFUNC(NONE,READ,2,raw_mov_b_rm,(W1 d, IMM s)) - -LOWFUNC(NONE,NONE,2,raw_mov_l_ri,(W4 d, IMM s)) -{ - MOVLir(s, d); -} -LENDFUNC(NONE,NONE,2,raw_mov_l_ri,(W4 d, IMM s)) - -LOWFUNC(NONE,NONE,2,raw_mov_w_ri,(W2 d, IMM s)) -{ - MOVWir(s, d); -} -LENDFUNC(NONE,NONE,2,raw_mov_w_ri,(W2 d, IMM s)) - -LOWFUNC(NONE,NONE,2,raw_mov_b_ri,(W1 d, IMM s)) -{ - MOVBir(s, d); -} -LENDFUNC(NONE,NONE,2,raw_mov_b_ri,(W1 d, IMM s)) - -LOWFUNC(RMW,RMW,2,raw_adc_l_mi,(MEMRW d, IMM s)) -{ - ADDR32 ADCLim(s, d, X86_NOREG, X86_NOREG, 1); -} -LENDFUNC(RMW,RMW,2,raw_adc_l_mi,(MEMRW d, IMM s)) - -LOWFUNC(WRITE,RMW,2,raw_add_l_mi,(IMM d, IMM s)) -{ - ADDR32 ADDLim(s, d, X86_NOREG, X86_NOREG, 1); -} -LENDFUNC(WRITE,RMW,2,raw_add_l_mi,(IMM d, IMM s)) - -LOWFUNC(WRITE,RMW,2,raw_add_w_mi,(IMM d, IMM s)) -{ - ADDR32 ADDWim(s, d, X86_NOREG, X86_NOREG, 1); -} -LENDFUNC(WRITE,RMW,2,raw_add_w_mi,(IMM d, IMM s)) - -LOWFUNC(WRITE,RMW,2,raw_add_b_mi,(IMM d, IMM s)) -{ - ADDR32 ADDBim(s, d, X86_NOREG, X86_NOREG, 1); -} -LENDFUNC(WRITE,RMW,2,raw_add_b_mi,(IMM d, IMM s)) - -LOWFUNC(WRITE,NONE,2,raw_test_l_ri,(R4 d, IMM i)) -{ - TESTLir(i, d); -} -LENDFUNC(WRITE,NONE,2,raw_test_l_ri,(R4 d, IMM i)) - -LOWFUNC(WRITE,NONE,2,raw_test_l_rr,(R4 d, R4 s)) -{ - TESTLrr(s, d); -} -LENDFUNC(WRITE,NONE,2,raw_test_l_rr,(R4 d, R4 s)) - -LOWFUNC(WRITE,NONE,2,raw_test_w_rr,(R2 d, R2 s)) -{ - TESTWrr(s, d); -} -LENDFUNC(WRITE,NONE,2,raw_test_w_rr,(R2 d, R2 s)) - -LOWFUNC(WRITE,NONE,2,raw_test_b_rr,(R1 d, R1 s)) -{ - TESTBrr(s, d); -} -LENDFUNC(WRITE,NONE,2,raw_test_b_rr,(R1 d, R1 s)) - -LOWFUNC(WRITE,NONE,2,raw_xor_l_ri,(RW4 d, IMM i)) -{ - XORLir(i, d); -} -LENDFUNC(WRITE,NONE,2,raw_xor_l_ri,(RW4 d, IMM i)) - -LOWFUNC(WRITE,NONE,2,raw_and_l_ri,(RW4 d, IMM i)) -{ - ANDLir(i, d); -} -LENDFUNC(WRITE,NONE,2,raw_and_l_ri,(RW4 d, IMM i)) - -LOWFUNC(WRITE,NONE,2,raw_and_w_ri,(RW2 d, IMM i)) -{ - ANDWir(i, d); -} -LENDFUNC(WRITE,NONE,2,raw_and_w_ri,(RW2 d, IMM i)) - -LOWFUNC(WRITE,NONE,2,raw_and_l,(RW4 d, R4 s)) -{ - ANDLrr(s, d); -} -LENDFUNC(WRITE,NONE,2,raw_and_l,(RW4 d, R4 s)) - -LOWFUNC(WRITE,NONE,2,raw_and_w,(RW2 d, R2 s)) -{ - ANDWrr(s, d); -} -LENDFUNC(WRITE,NONE,2,raw_and_w,(RW2 d, R2 s)) - -LOWFUNC(WRITE,NONE,2,raw_and_b,(RW1 d, R1 s)) -{ - ANDBrr(s, d); -} -LENDFUNC(WRITE,NONE,2,raw_and_b,(RW1 d, R1 s)) - -LOWFUNC(WRITE,NONE,2,raw_or_l_ri,(RW4 d, IMM i)) -{ - ORLir(i, d); -} -LENDFUNC(WRITE,NONE,2,raw_or_l_ri,(RW4 d, IMM i)) - -LOWFUNC(WRITE,NONE,2,raw_or_l,(RW4 d, R4 s)) -{ - ORLrr(s, d); -} -LENDFUNC(WRITE,NONE,2,raw_or_l,(RW4 d, R4 s)) - -LOWFUNC(WRITE,NONE,2,raw_or_w,(RW2 d, R2 s)) -{ - ORWrr(s, d); -} -LENDFUNC(WRITE,NONE,2,raw_or_w,(RW2 d, R2 s)) - -LOWFUNC(WRITE,NONE,2,raw_or_b,(RW1 d, R1 s)) -{ - ORBrr(s, d); -} -LENDFUNC(WRITE,NONE,2,raw_or_b,(RW1 d, R1 s)) - -LOWFUNC(RMW,NONE,2,raw_adc_l,(RW4 d, R4 s)) -{ - ADCLrr(s, d); -} -LENDFUNC(RMW,NONE,2,raw_adc_l,(RW4 d, R4 s)) - -LOWFUNC(RMW,NONE,2,raw_adc_w,(RW2 d, R2 s)) -{ - ADCWrr(s, d); -} -LENDFUNC(RMW,NONE,2,raw_adc_w,(RW2 d, R2 s)) - -LOWFUNC(RMW,NONE,2,raw_adc_b,(RW1 d, R1 s)) -{ - ADCBrr(s, d); -} -LENDFUNC(RMW,NONE,2,raw_adc_b,(RW1 d, R1 s)) - -LOWFUNC(WRITE,NONE,2,raw_add_l,(RW4 d, R4 s)) -{ - ADDLrr(s, d); -} -LENDFUNC(WRITE,NONE,2,raw_add_l,(RW4 d, R4 s)) - -LOWFUNC(WRITE,NONE,2,raw_add_w,(RW2 d, R2 s)) -{ - ADDWrr(s, d); -} -LENDFUNC(WRITE,NONE,2,raw_add_w,(RW2 d, R2 s)) - -LOWFUNC(WRITE,NONE,2,raw_add_b,(RW1 d, R1 s)) -{ - ADDBrr(s, d); -} -LENDFUNC(WRITE,NONE,2,raw_add_b,(RW1 d, R1 s)) - -LOWFUNC(WRITE,NONE,2,raw_sub_l_ri,(RW4 d, IMM i)) -{ - SUBLir(i, d); -} -LENDFUNC(WRITE,NONE,2,raw_sub_l_ri,(RW4 d, IMM i)) - -LOWFUNC(WRITE,NONE,2,raw_sub_b_ri,(RW1 d, IMM i)) -{ - SUBBir(i, d); -} -LENDFUNC(WRITE,NONE,2,raw_sub_b_ri,(RW1 d, IMM i)) - -LOWFUNC(WRITE,NONE,2,raw_add_l_ri,(RW4 d, IMM i)) -{ - ADDLir(i, d); -} -LENDFUNC(WRITE,NONE,2,raw_add_l_ri,(RW4 d, IMM i)) - -LOWFUNC(WRITE,NONE,2,raw_add_w_ri,(RW2 d, IMM i)) -{ - ADDWir(i, d); -} -LENDFUNC(WRITE,NONE,2,raw_add_w_ri,(RW2 d, IMM i)) - -LOWFUNC(WRITE,NONE,2,raw_add_b_ri,(RW1 d, IMM i)) -{ - ADDBir(i, d); -} -LENDFUNC(WRITE,NONE,2,raw_add_b_ri,(RW1 d, IMM i)) - -LOWFUNC(RMW,NONE,2,raw_sbb_l,(RW4 d, R4 s)) -{ - SBBLrr(s, d); -} -LENDFUNC(RMW,NONE,2,raw_sbb_l,(RW4 d, R4 s)) - -LOWFUNC(RMW,NONE,2,raw_sbb_w,(RW2 d, R2 s)) -{ - SBBWrr(s, d); -} -LENDFUNC(RMW,NONE,2,raw_sbb_w,(RW2 d, R2 s)) - -LOWFUNC(RMW,NONE,2,raw_sbb_b,(RW1 d, R1 s)) -{ - SBBBrr(s, d); -} -LENDFUNC(RMW,NONE,2,raw_sbb_b,(RW1 d, R1 s)) - -LOWFUNC(WRITE,NONE,2,raw_sub_l,(RW4 d, R4 s)) -{ - SUBLrr(s, d); -} -LENDFUNC(WRITE,NONE,2,raw_sub_l,(RW4 d, R4 s)) - -LOWFUNC(WRITE,NONE,2,raw_sub_w,(RW2 d, R2 s)) -{ - SUBWrr(s, d); -} -LENDFUNC(WRITE,NONE,2,raw_sub_w,(RW2 d, R2 s)) - -LOWFUNC(WRITE,NONE,2,raw_sub_b,(RW1 d, R1 s)) -{ - SUBBrr(s, d); -} -LENDFUNC(WRITE,NONE,2,raw_sub_b,(RW1 d, R1 s)) - -LOWFUNC(WRITE,NONE,2,raw_cmp_l,(R4 d, R4 s)) -{ - CMPLrr(s, d); -} -LENDFUNC(WRITE,NONE,2,raw_cmp_l,(R4 d, R4 s)) - -LOWFUNC(WRITE,NONE,2,raw_cmp_l_ri,(R4 r, IMM i)) -{ - CMPLir(i, r); -} -LENDFUNC(WRITE,NONE,2,raw_cmp_l_ri,(R4 r, IMM i)) - -LOWFUNC(WRITE,NONE,2,raw_cmp_w,(R2 d, R2 s)) -{ - CMPWrr(s, d); -} -LENDFUNC(WRITE,NONE,2,raw_cmp_w,(R2 d, R2 s)) - -LOWFUNC(WRITE,READ,2,raw_cmp_b_mi,(MEMR d, IMM s)) -{ - ADDR32 CMPBim(s, d, X86_NOREG, X86_NOREG, 1); -} -LENDFUNC(WRITE,READ,2,raw_cmp_b_mi,(MEMR d, IMM s)) - -LOWFUNC(WRITE,NONE,2,raw_cmp_b_ri,(R1 d, IMM i)) -{ - CMPBir(i, d); -} -LENDFUNC(WRITE,NONE,2,raw_cmp_b_ri,(R1 d, IMM i)) - -LOWFUNC(WRITE,NONE,2,raw_cmp_b,(R1 d, R1 s)) -{ - CMPBrr(s, d); -} -LENDFUNC(WRITE,NONE,2,raw_cmp_b,(R1 d, R1 s)) - -LOWFUNC(WRITE,READ,4,raw_cmp_l_rm_indexed,(R4 d, IMM offset, R4 index, IMM factor)) -{ - ADDR32 CMPLmr(offset, X86_NOREG, index, factor, d); -} -LENDFUNC(WRITE,READ,4,raw_cmp_l_rm_indexed,(R4 d, IMM offset, R4 index, IMM factor)) - -LOWFUNC(WRITE,NONE,2,raw_xor_l,(RW4 d, R4 s)) -{ - XORLrr(s, d); -} -LENDFUNC(WRITE,NONE,2,raw_xor_l,(RW4 d, R4 s)) - -LOWFUNC(WRITE,NONE,2,raw_xor_w,(RW2 d, R2 s)) -{ - XORWrr(s, d); -} -LENDFUNC(WRITE,NONE,2,raw_xor_w,(RW2 d, R2 s)) - -LOWFUNC(WRITE,NONE,2,raw_xor_b,(RW1 d, R1 s)) -{ - XORBrr(s, d); -} -LENDFUNC(WRITE,NONE,2,raw_xor_b,(RW1 d, R1 s)) - -LOWFUNC(WRITE,RMW,2,raw_sub_l_mi,(MEMRW d, IMM s)) -{ - ADDR32 SUBLim(s, d, X86_NOREG, X86_NOREG, 1); -} -LENDFUNC(WRITE,RMW,2,raw_sub_l_mi,(MEMRW d, IMM s)) - -LOWFUNC(WRITE,READ,2,raw_cmp_l_mi,(MEMR d, IMM s)) -{ - ADDR32 CMPLim(s, d, X86_NOREG, X86_NOREG, 1); -} -LENDFUNC(WRITE,READ,2,raw_cmp_l_mi,(MEMR d, IMM s)) - -LOWFUNC(NONE,NONE,2,raw_xchg_l_rr,(RW4 r1, RW4 r2)) -{ - XCHGLrr(r2, r1); -} -LENDFUNC(NONE,NONE,2,raw_xchg_l_rr,(RW4 r1, RW4 r2)) - -LOWFUNC(NONE,NONE,2,raw_xchg_b_rr,(RW4 r1, RW4 r2)) -{ - XCHGBrr(r2, r1); -} -LENDFUNC(NONE,NONE,2,raw_xchg_b_rr,(RW4 r1, RW4 r2)) - -LOWFUNC(READ,WRITE,0,raw_pushfl,(void)) -{ - PUSHF(); -} -LENDFUNC(READ,WRITE,0,raw_pushfl,(void)) - -LOWFUNC(WRITE,READ,0,raw_popfl,(void)) -{ - POPF(); -} -LENDFUNC(WRITE,READ,0,raw_popfl,(void)) - -/* Generate floating-point instructions */ -static inline void x86_fadd_m(MEMR s) -{ - ADDR32 FADDLm(s,X86_NOREG,X86_NOREG,1); -} - -#else /* !USE_NEW_RTASM */ - -const bool optimize_accum = true; -const bool optimize_imm8 = true; -const bool optimize_shift_once = true; - -/************************************************************************* - * Actual encoding of the instructions on the target CPU * - *************************************************************************/ - -static inline int isaccum(int r) -{ - return (r == EAX_INDEX); -} - -static inline int isbyte(uae_s32 x) -{ - return (x>=-128 && x<=127); -} - -static inline int isword(uae_s32 x) -{ - return (x>=-32768 && x<=32767); -} - -LOWFUNC(NONE,WRITE,1,raw_push_l_r,(R4 r)) -{ - emit_byte(0x50+r); -} -LENDFUNC(NONE,WRITE,1,raw_push_l_r,(R4 r)) - -LOWFUNC(NONE,READ,1,raw_pop_l_r,(R4 r)) -{ - emit_byte(0x58+r); -} -LENDFUNC(NONE,READ,1,raw_pop_l_r,(R4 r)) - -LOWFUNC(NONE,READ,1,raw_pop_l_m,(MEMW d)) -{ - emit_byte(0x8f); - emit_byte(0x05); - emit_long(d); -} -LENDFUNC(NONE,READ,1,raw_pop_l_m,(MEMW d)) - -LOWFUNC(WRITE,NONE,2,raw_bt_l_ri,(R4 r, IMM i)) -{ - emit_byte(0x0f); - emit_byte(0xba); - emit_byte(0xe0+r); - emit_byte(i); -} -LENDFUNC(WRITE,NONE,2,raw_bt_l_ri,(R4 r, IMM i)) - -LOWFUNC(WRITE,NONE,2,raw_bt_l_rr,(R4 r, R4 b)) -{ - emit_byte(0x0f); - emit_byte(0xa3); - emit_byte(0xc0+8*b+r); -} -LENDFUNC(WRITE,NONE,2,raw_bt_l_rr,(R4 r, R4 b)) - -LOWFUNC(WRITE,NONE,2,raw_btc_l_ri,(RW4 r, IMM i)) -{ - emit_byte(0x0f); - emit_byte(0xba); - emit_byte(0xf8+r); - emit_byte(i); -} -LENDFUNC(WRITE,NONE,2,raw_btc_l_ri,(RW4 r, IMM i)) - -LOWFUNC(WRITE,NONE,2,raw_btc_l_rr,(RW4 r, R4 b)) -{ - emit_byte(0x0f); - emit_byte(0xbb); - emit_byte(0xc0+8*b+r); -} -LENDFUNC(WRITE,NONE,2,raw_btc_l_rr,(RW4 r, R4 b)) - - -LOWFUNC(WRITE,NONE,2,raw_btr_l_ri,(RW4 r, IMM i)) -{ - emit_byte(0x0f); - emit_byte(0xba); - emit_byte(0xf0+r); - emit_byte(i); -} -LENDFUNC(WRITE,NONE,2,raw_btr_l_ri,(RW4 r, IMM i)) - -LOWFUNC(WRITE,NONE,2,raw_btr_l_rr,(RW4 r, R4 b)) -{ - emit_byte(0x0f); - emit_byte(0xb3); - emit_byte(0xc0+8*b+r); -} -LENDFUNC(WRITE,NONE,2,raw_btr_l_rr,(RW4 r, R4 b)) - -LOWFUNC(WRITE,NONE,2,raw_bts_l_ri,(RW4 r, IMM i)) -{ - emit_byte(0x0f); - emit_byte(0xba); - emit_byte(0xe8+r); - emit_byte(i); -} -LENDFUNC(WRITE,NONE,2,raw_bts_l_ri,(RW4 r, IMM i)) - -LOWFUNC(WRITE,NONE,2,raw_bts_l_rr,(RW4 r, R4 b)) -{ - emit_byte(0x0f); - emit_byte(0xab); - emit_byte(0xc0+8*b+r); -} -LENDFUNC(WRITE,NONE,2,raw_bts_l_rr,(RW4 r, R4 b)) - -LOWFUNC(WRITE,NONE,2,raw_sub_w_ri,(RW2 d, IMM i)) -{ - emit_byte(0x66); - if (isbyte(i)) { - emit_byte(0x83); - emit_byte(0xe8+d); - emit_byte(i); - } - else { - if (optimize_accum && isaccum(d)) - emit_byte(0x2d); - else { - emit_byte(0x81); - emit_byte(0xe8+d); - } - emit_word(i); - } -} -LENDFUNC(WRITE,NONE,2,raw_sub_w_ri,(RW2 d, IMM i)) - - -LOWFUNC(NONE,READ,2,raw_mov_l_rm,(W4 d, MEMR s)) -{ - emit_byte(0x8b); - emit_byte(0x05+8*d); - emit_long(s); -} -LENDFUNC(NONE,READ,2,raw_mov_l_rm,(W4 d, MEMR s)) - -LOWFUNC(NONE,WRITE,2,raw_mov_l_mi,(MEMW d, IMM s)) -{ - emit_byte(0xc7); - emit_byte(0x05); - emit_long(d); - emit_long(s); -} -LENDFUNC(NONE,WRITE,2,raw_mov_l_mi,(MEMW d, IMM s)) - -LOWFUNC(NONE,WRITE,2,raw_mov_w_mi,(MEMW d, IMM s)) -{ - emit_byte(0x66); - emit_byte(0xc7); - emit_byte(0x05); - emit_long(d); - emit_word(s); -} -LENDFUNC(NONE,WRITE,2,raw_mov_w_mi,(MEMW d, IMM s)) - -LOWFUNC(NONE,WRITE,2,raw_mov_b_mi,(MEMW d, IMM s)) -{ - emit_byte(0xc6); - emit_byte(0x05); - emit_long(d); - emit_byte(s); -} -LENDFUNC(NONE,WRITE,2,raw_mov_b_mi,(MEMW d, IMM s)) - -LOWFUNC(WRITE,RMW,2,raw_rol_b_mi,(MEMRW d, IMM i)) -{ - if (optimize_shift_once && (i == 1)) { - emit_byte(0xd0); - emit_byte(0x05); - emit_long(d); - } - else { - emit_byte(0xc0); - emit_byte(0x05); - emit_long(d); - emit_byte(i); - } -} -LENDFUNC(WRITE,RMW,2,raw_rol_b_mi,(MEMRW d, IMM i)) - -LOWFUNC(WRITE,NONE,2,raw_rol_b_ri,(RW1 r, IMM i)) -{ - if (optimize_shift_once && (i == 1)) { - emit_byte(0xd0); - emit_byte(0xc0+r); - } - else { - emit_byte(0xc0); - emit_byte(0xc0+r); - emit_byte(i); - } -} -LENDFUNC(WRITE,NONE,2,raw_rol_b_ri,(RW1 r, IMM i)) - -LOWFUNC(WRITE,NONE,2,raw_rol_w_ri,(RW2 r, IMM i)) -{ - emit_byte(0x66); - emit_byte(0xc1); - emit_byte(0xc0+r); - emit_byte(i); -} -LENDFUNC(WRITE,NONE,2,raw_rol_w_ri,(RW2 r, IMM i)) - -LOWFUNC(WRITE,NONE,2,raw_rol_l_ri,(RW4 r, IMM i)) -{ - if (optimize_shift_once && (i == 1)) { - emit_byte(0xd1); - emit_byte(0xc0+r); - } - else { - emit_byte(0xc1); - emit_byte(0xc0+r); - emit_byte(i); - } -} -LENDFUNC(WRITE,NONE,2,raw_rol_l_ri,(RW4 r, IMM i)) - -LOWFUNC(WRITE,NONE,2,raw_rol_l_rr,(RW4 d, R1 r)) -{ - emit_byte(0xd3); - emit_byte(0xc0+d); -} -LENDFUNC(WRITE,NONE,2,raw_rol_l_rr,(RW4 d, R1 r)) - -LOWFUNC(WRITE,NONE,2,raw_rol_w_rr,(RW2 d, R1 r)) -{ - emit_byte(0x66); - emit_byte(0xd3); - emit_byte(0xc0+d); -} -LENDFUNC(WRITE,NONE,2,raw_rol_w_rr,(RW2 d, R1 r)) - -LOWFUNC(WRITE,NONE,2,raw_rol_b_rr,(RW1 d, R1 r)) -{ - emit_byte(0xd2); - emit_byte(0xc0+d); -} -LENDFUNC(WRITE,NONE,2,raw_rol_b_rr,(RW1 d, R1 r)) - -LOWFUNC(WRITE,NONE,2,raw_shll_l_rr,(RW4 d, R1 r)) -{ - emit_byte(0xd3); - emit_byte(0xe0+d); -} -LENDFUNC(WRITE,NONE,2,raw_shll_l_rr,(RW4 d, R1 r)) - -LOWFUNC(WRITE,NONE,2,raw_shll_w_rr,(RW2 d, R1 r)) -{ - emit_byte(0x66); - emit_byte(0xd3); - emit_byte(0xe0+d); -} -LENDFUNC(WRITE,NONE,2,raw_shll_w_rr,(RW2 d, R1 r)) - -LOWFUNC(WRITE,NONE,2,raw_shll_b_rr,(RW1 d, R1 r)) -{ - emit_byte(0xd2); - emit_byte(0xe0+d); -} -LENDFUNC(WRITE,NONE,2,raw_shll_b_rr,(RW1 d, R1 r)) - -LOWFUNC(WRITE,NONE,2,raw_ror_b_ri,(RW1 r, IMM i)) -{ - if (optimize_shift_once && (i == 1)) { - emit_byte(0xd0); - emit_byte(0xc8+r); - } - else { - emit_byte(0xc0); - emit_byte(0xc8+r); - emit_byte(i); - } -} -LENDFUNC(WRITE,NONE,2,raw_ror_b_ri,(RW1 r, IMM i)) - -LOWFUNC(WRITE,NONE,2,raw_ror_w_ri,(RW2 r, IMM i)) -{ - emit_byte(0x66); - emit_byte(0xc1); - emit_byte(0xc8+r); - emit_byte(i); -} -LENDFUNC(WRITE,NONE,2,raw_ror_w_ri,(RW2 r, IMM i)) - -// gb-- used for making an fpcr value in compemu_fpp.cpp -LOWFUNC(WRITE,READ,2,raw_or_l_rm,(RW4 d, MEMR s)) -{ - emit_byte(0x0b); - emit_byte(0x05+8*d); - emit_long(s); -} -LENDFUNC(WRITE,READ,2,raw_or_l_rm,(RW4 d, MEMR s)) - -LOWFUNC(WRITE,NONE,2,raw_ror_l_ri,(RW4 r, IMM i)) -{ - if (optimize_shift_once && (i == 1)) { - emit_byte(0xd1); - emit_byte(0xc8+r); - } - else { - emit_byte(0xc1); - emit_byte(0xc8+r); - emit_byte(i); - } -} -LENDFUNC(WRITE,NONE,2,raw_ror_l_ri,(RW4 r, IMM i)) - -LOWFUNC(WRITE,NONE,2,raw_ror_l_rr,(RW4 d, R1 r)) -{ - emit_byte(0xd3); - emit_byte(0xc8+d); -} -LENDFUNC(WRITE,NONE,2,raw_ror_l_rr,(RW4 d, R1 r)) - -LOWFUNC(WRITE,NONE,2,raw_ror_w_rr,(RW2 d, R1 r)) -{ - emit_byte(0x66); - emit_byte(0xd3); - emit_byte(0xc8+d); -} -LENDFUNC(WRITE,NONE,2,raw_ror_w_rr,(RW2 d, R1 r)) - -LOWFUNC(WRITE,NONE,2,raw_ror_b_rr,(RW1 d, R1 r)) -{ - emit_byte(0xd2); - emit_byte(0xc8+d); -} -LENDFUNC(WRITE,NONE,2,raw_ror_b_rr,(RW1 d, R1 r)) - -LOWFUNC(WRITE,NONE,2,raw_shrl_l_rr,(RW4 d, R1 r)) -{ - emit_byte(0xd3); - emit_byte(0xe8+d); -} -LENDFUNC(WRITE,NONE,2,raw_shrl_l_rr,(RW4 d, R1 r)) - -LOWFUNC(WRITE,NONE,2,raw_shrl_w_rr,(RW2 d, R1 r)) -{ - emit_byte(0x66); - emit_byte(0xd3); - emit_byte(0xe8+d); -} -LENDFUNC(WRITE,NONE,2,raw_shrl_w_rr,(RW2 d, R1 r)) - -LOWFUNC(WRITE,NONE,2,raw_shrl_b_rr,(RW1 d, R1 r)) -{ - emit_byte(0xd2); - emit_byte(0xe8+d); -} -LENDFUNC(WRITE,NONE,2,raw_shrl_b_rr,(RW1 d, R1 r)) - -LOWFUNC(WRITE,NONE,2,raw_shra_l_rr,(RW4 d, R1 r)) -{ - emit_byte(0xd3); - emit_byte(0xf8+d); -} -LENDFUNC(WRITE,NONE,2,raw_shra_l_rr,(RW4 d, R1 r)) - -LOWFUNC(WRITE,NONE,2,raw_shra_w_rr,(RW2 d, R1 r)) -{ - emit_byte(0x66); - emit_byte(0xd3); - emit_byte(0xf8+d); -} -LENDFUNC(WRITE,NONE,2,raw_shra_w_rr,(RW2 d, R1 r)) - -LOWFUNC(WRITE,NONE,2,raw_shra_b_rr,(RW1 d, R1 r)) -{ - emit_byte(0xd2); - emit_byte(0xf8+d); -} -LENDFUNC(WRITE,NONE,2,raw_shra_b_rr,(RW1 d, R1 r)) - -LOWFUNC(WRITE,NONE,2,raw_shll_l_ri,(RW4 r, IMM i)) -{ - if (optimize_shift_once && (i == 1)) { - emit_byte(0xd1); - emit_byte(0xe0+r); - } - else { - emit_byte(0xc1); - emit_byte(0xe0+r); - emit_byte(i); - } -} -LENDFUNC(WRITE,NONE,2,raw_shll_l_ri,(RW4 r, IMM i)) - -LOWFUNC(WRITE,NONE,2,raw_shll_w_ri,(RW2 r, IMM i)) -{ - emit_byte(0x66); - emit_byte(0xc1); - emit_byte(0xe0+r); - emit_byte(i); -} -LENDFUNC(WRITE,NONE,2,raw_shll_w_ri,(RW2 r, IMM i)) - -LOWFUNC(WRITE,NONE,2,raw_shll_b_ri,(RW1 r, IMM i)) -{ - if (optimize_shift_once && (i == 1)) { - emit_byte(0xd0); - emit_byte(0xe0+r); - } - else { - emit_byte(0xc0); - emit_byte(0xe0+r); - emit_byte(i); - } -} -LENDFUNC(WRITE,NONE,2,raw_shll_b_ri,(RW1 r, IMM i)) - -LOWFUNC(WRITE,NONE,2,raw_shrl_l_ri,(RW4 r, IMM i)) -{ - if (optimize_shift_once && (i == 1)) { - emit_byte(0xd1); - emit_byte(0xe8+r); - } - else { - emit_byte(0xc1); - emit_byte(0xe8+r); - emit_byte(i); - } -} -LENDFUNC(WRITE,NONE,2,raw_shrl_l_ri,(RW4 r, IMM i)) - -LOWFUNC(WRITE,NONE,2,raw_shrl_w_ri,(RW2 r, IMM i)) -{ - emit_byte(0x66); - emit_byte(0xc1); - emit_byte(0xe8+r); - emit_byte(i); -} -LENDFUNC(WRITE,NONE,2,raw_shrl_w_ri,(RW2 r, IMM i)) - -LOWFUNC(WRITE,NONE,2,raw_shrl_b_ri,(RW1 r, IMM i)) -{ - if (optimize_shift_once && (i == 1)) { - emit_byte(0xd0); - emit_byte(0xe8+r); - } - else { - emit_byte(0xc0); - emit_byte(0xe8+r); - emit_byte(i); - } -} -LENDFUNC(WRITE,NONE,2,raw_shrl_b_ri,(RW1 r, IMM i)) - -LOWFUNC(WRITE,NONE,2,raw_shra_l_ri,(RW4 r, IMM i)) -{ - if (optimize_shift_once && (i == 1)) { - emit_byte(0xd1); - emit_byte(0xf8+r); - } - else { - emit_byte(0xc1); - emit_byte(0xf8+r); - emit_byte(i); - } -} -LENDFUNC(WRITE,NONE,2,raw_shra_l_ri,(RW4 r, IMM i)) - -LOWFUNC(WRITE,NONE,2,raw_shra_w_ri,(RW2 r, IMM i)) -{ - emit_byte(0x66); - emit_byte(0xc1); - emit_byte(0xf8+r); - emit_byte(i); -} -LENDFUNC(WRITE,NONE,2,raw_shra_w_ri,(RW2 r, IMM i)) - -LOWFUNC(WRITE,NONE,2,raw_shra_b_ri,(RW1 r, IMM i)) -{ - if (optimize_shift_once && (i == 1)) { - emit_byte(0xd0); - emit_byte(0xf8+r); - } - else { - emit_byte(0xc0); - emit_byte(0xf8+r); - emit_byte(i); - } -} -LENDFUNC(WRITE,NONE,2,raw_shra_b_ri,(RW1 r, IMM i)) - -LOWFUNC(WRITE,NONE,1,raw_sahf,(R2 dummy_ah)) -{ - emit_byte(0x9e); -} -LENDFUNC(WRITE,NONE,1,raw_sahf,(R2 dummy_ah)) - -LOWFUNC(NONE,NONE,1,raw_cpuid,(R4 dummy_eax)) -{ - emit_byte(0x0f); - emit_byte(0xa2); -} -LENDFUNC(NONE,NONE,1,raw_cpuid,(R4 dummy_eax)) - -LOWFUNC(READ,NONE,1,raw_lahf,(W2 dummy_ah)) -{ - emit_byte(0x9f); -} -LENDFUNC(READ,NONE,1,raw_lahf,(W2 dummy_ah)) - -LOWFUNC(READ,NONE,2,raw_setcc,(W1 d, IMM cc)) -{ - emit_byte(0x0f); - emit_byte(0x90+cc); - emit_byte(0xc0+d); -} -LENDFUNC(READ,NONE,2,raw_setcc,(W1 d, IMM cc)) - -LOWFUNC(READ,WRITE,2,raw_setcc_m,(MEMW d, IMM cc)) -{ - emit_byte(0x0f); - emit_byte(0x90+cc); - emit_byte(0x05); - emit_long(d); -} -LENDFUNC(READ,WRITE,2,raw_setcc_m,(MEMW d, IMM cc)) - -LOWFUNC(READ,NONE,3,raw_cmov_l_rr,(RW4 d, R4 s, IMM cc)) -{ - if (have_cmov) { - emit_byte(0x0f); - emit_byte(0x40+cc); - emit_byte(0xc0+8*d+s); - } - else { /* replacement using branch and mov */ - int uncc=(cc^1); - emit_byte(0x70+uncc); - emit_byte(2); /* skip next 2 bytes if not cc=true */ - emit_byte(0x89); - emit_byte(0xc0+8*s+d); - } -} -LENDFUNC(READ,NONE,3,raw_cmov_l_rr,(RW4 d, R4 s, IMM cc)) - -LOWFUNC(WRITE,NONE,2,raw_bsf_l_rr,(W4 d, R4 s)) -{ - emit_byte(0x0f); - emit_byte(0xbc); - emit_byte(0xc0+8*d+s); -} -LENDFUNC(WRITE,NONE,2,raw_bsf_l_rr,(W4 d, R4 s)) - -LOWFUNC(NONE,NONE,2,raw_sign_extend_16_rr,(W4 d, R2 s)) -{ - emit_byte(0x0f); - emit_byte(0xbf); - emit_byte(0xc0+8*d+s); -} -LENDFUNC(NONE,NONE,2,raw_sign_extend_16_rr,(W4 d, R2 s)) - -LOWFUNC(NONE,NONE,2,raw_sign_extend_8_rr,(W4 d, R1 s)) -{ - emit_byte(0x0f); - emit_byte(0xbe); - emit_byte(0xc0+8*d+s); -} -LENDFUNC(NONE,NONE,2,raw_sign_extend_8_rr,(W4 d, R1 s)) - -LOWFUNC(NONE,NONE,2,raw_zero_extend_16_rr,(W4 d, R2 s)) -{ - emit_byte(0x0f); - emit_byte(0xb7); - emit_byte(0xc0+8*d+s); -} -LENDFUNC(NONE,NONE,2,raw_zero_extend_16_rr,(W4 d, R2 s)) - -LOWFUNC(NONE,NONE,2,raw_zero_extend_8_rr,(W4 d, R1 s)) -{ - emit_byte(0x0f); - emit_byte(0xb6); - emit_byte(0xc0+8*d+s); -} -LENDFUNC(NONE,NONE,2,raw_zero_extend_8_rr,(W4 d, R1 s)) - -LOWFUNC(NONE,NONE,2,raw_imul_32_32,(RW4 d, R4 s)) -{ - emit_byte(0x0f); - emit_byte(0xaf); - emit_byte(0xc0+8*d+s); -} -LENDFUNC(NONE,NONE,2,raw_imul_32_32,(RW4 d, R4 s)) - -LOWFUNC(NONE,NONE,2,raw_imul_64_32,(RW4 d, RW4 s)) -{ - if (d!=MUL_NREG1 || s!=MUL_NREG2) { - jit_abort("Bad register in IMUL: d=%d, s=%d\n",d,s); - } - emit_byte(0xf7); - emit_byte(0xea); -} -LENDFUNC(NONE,NONE,2,raw_imul_64_32,(RW4 d, RW4 s)) - -LOWFUNC(NONE,NONE,2,raw_mul_64_32,(RW4 d, RW4 s)) -{ - if (d!=MUL_NREG1 || s!=MUL_NREG2) { - jit_abort("Bad register in MUL: d=%d, s=%d",d,s); - } - emit_byte(0xf7); - emit_byte(0xe2); -} -LENDFUNC(NONE,NONE,2,raw_mul_64_32,(RW4 d, RW4 s)) - -LOWFUNC(NONE,NONE,2,raw_mul_32_32,(RW4 d, R4 s)) -{ - jit_abort("unsupported MUL"); /* %^$&%^$%#^ x86! */ - emit_byte(0x0f); - emit_byte(0xaf); - emit_byte(0xc0+8*d+s); -} -LENDFUNC(NONE,NONE,2,raw_mul_32_32,(RW4 d, R4 s)) - -LOWFUNC(NONE,NONE,2,raw_mov_b_rr,(W1 d, R1 s)) -{ - emit_byte(0x88); - emit_byte(0xc0+8*s+d); -} -LENDFUNC(NONE,NONE,2,raw_mov_b_rr,(W1 d, R1 s)) - -LOWFUNC(NONE,NONE,2,raw_mov_w_rr,(W2 d, R2 s)) -{ - emit_byte(0x66); - emit_byte(0x89); - emit_byte(0xc0+8*s+d); -} -LENDFUNC(NONE,NONE,2,raw_mov_w_rr,(W2 d, R2 s)) - -LOWFUNC(NONE,READ,4,raw_mov_l_rrm_indexed,(W4 d,R4 baser, R4 index, IMM factor)) -{ - int isebp=(baser==5)?0x40:0; - int fi; - - switch(factor) { - case 1: fi=0; break; - case 2: fi=1; break; - case 4: fi=2; break; - case 8: fi=3; break; - default: abort(); - } - - - emit_byte(0x8b); - emit_byte(0x04+8*d+isebp); - emit_byte(baser+8*index+0x40*fi); - if (isebp) - emit_byte(0x00); -} -LENDFUNC(NONE,READ,4,raw_mov_l_rrm_indexed,(W4 d,R4 baser, R4 index, IMM factor)) - -LOWFUNC(NONE,READ,4,raw_mov_w_rrm_indexed,(W2 d, R4 baser, R4 index, IMM factor)) -{ - int fi; - int isebp; - - switch(factor) { - case 1: fi=0; break; - case 2: fi=1; break; - case 4: fi=2; break; - case 8: fi=3; break; - default: abort(); - } - isebp=(baser==5)?0x40:0; - - emit_byte(0x66); - emit_byte(0x8b); - emit_byte(0x04+8*d+isebp); - emit_byte(baser+8*index+0x40*fi); - if (isebp) - emit_byte(0x00); -} -LENDFUNC(NONE,READ,4,raw_mov_w_rrm_indexed,(W2 d, R4 baser, R4 index, IMM factor)) - -LOWFUNC(NONE,READ,4,raw_mov_b_rrm_indexed,(W1 d, R4 baser, R4 index, IMM factor)) -{ - int fi; - int isebp; - - switch(factor) { - case 1: fi=0; break; - case 2: fi=1; break; - case 4: fi=2; break; - case 8: fi=3; break; - default: abort(); - } - isebp=(baser==5)?0x40:0; - - emit_byte(0x8a); - emit_byte(0x04+8*d+isebp); - emit_byte(baser+8*index+0x40*fi); - if (isebp) - emit_byte(0x00); -} -LENDFUNC(NONE,READ,4,raw_mov_b_rrm_indexed,(W1 d, R4 baser, R4 index, IMM factor)) - -LOWFUNC(NONE,WRITE,4,raw_mov_l_mrr_indexed,(R4 baser, R4 index, IMM factor, R4 s)) -{ - int fi; - int isebp; - - switch(factor) { - case 1: fi=0; break; - case 2: fi=1; break; - case 4: fi=2; break; - case 8: fi=3; break; - default: abort(); - } - - - isebp=(baser==5)?0x40:0; - - emit_byte(0x89); - emit_byte(0x04+8*s+isebp); - emit_byte(baser+8*index+0x40*fi); - if (isebp) - emit_byte(0x00); -} -LENDFUNC(NONE,WRITE,4,raw_mov_l_mrr_indexed,(R4 baser, R4 index, IMM factor, R4 s)) - -LOWFUNC(NONE,WRITE,4,raw_mov_w_mrr_indexed,(R4 baser, R4 index, IMM factor, R2 s)) -{ - int fi; - int isebp; - - switch(factor) { - case 1: fi=0; break; - case 2: fi=1; break; - case 4: fi=2; break; - case 8: fi=3; break; - default: abort(); - } - isebp=(baser==5)?0x40:0; - - emit_byte(0x66); - emit_byte(0x89); - emit_byte(0x04+8*s+isebp); - emit_byte(baser+8*index+0x40*fi); - if (isebp) - emit_byte(0x00); -} -LENDFUNC(NONE,WRITE,4,raw_mov_w_mrr_indexed,(R4 baser, R4 index, IMM factor, R2 s)) - -LOWFUNC(NONE,WRITE,4,raw_mov_b_mrr_indexed,(R4 baser, R4 index, IMM factor, R1 s)) -{ - int fi; - int isebp; - - switch(factor) { - case 1: fi=0; break; - case 2: fi=1; break; - case 4: fi=2; break; - case 8: fi=3; break; - default: abort(); - } - isebp=(baser==5)?0x40:0; - - emit_byte(0x88); - emit_byte(0x04+8*s+isebp); - emit_byte(baser+8*index+0x40*fi); - if (isebp) - emit_byte(0x00); -} -LENDFUNC(NONE,WRITE,4,raw_mov_b_mrr_indexed,(R4 baser, R4 index, IMM factor, R1 s)) - -LOWFUNC(NONE,WRITE,5,raw_mov_l_bmrr_indexed,(IMM base, R4 baser, R4 index, IMM factor, R4 s)) -{ - int fi; - - switch(factor) { - case 1: fi=0; break; - case 2: fi=1; break; - case 4: fi=2; break; - case 8: fi=3; break; - default: abort(); - } - - emit_byte(0x89); - emit_byte(0x84+8*s); - emit_byte(baser+8*index+0x40*fi); - emit_long(base); -} -LENDFUNC(NONE,WRITE,5,raw_mov_l_bmrr_indexed,(IMM base, R4 baser, R4 index, IMM factor, R4 s)) - -LOWFUNC(NONE,WRITE,5,raw_mov_w_bmrr_indexed,(IMM base, R4 baser, R4 index, IMM factor, R2 s)) -{ - int fi; - - switch(factor) { - case 1: fi=0; break; - case 2: fi=1; break; - case 4: fi=2; break; - case 8: fi=3; break; - default: abort(); - } - - emit_byte(0x66); - emit_byte(0x89); - emit_byte(0x84+8*s); - emit_byte(baser+8*index+0x40*fi); - emit_long(base); -} -LENDFUNC(NONE,WRITE,5,raw_mov_w_bmrr_indexed,(IMM base, R4 baser, R4 index, IMM factor, R2 s)) - -LOWFUNC(NONE,WRITE,5,raw_mov_b_bmrr_indexed,(IMM base, R4 baser, R4 index, IMM factor, R1 s)) -{ - int fi; - - switch(factor) { - case 1: fi=0; break; - case 2: fi=1; break; - case 4: fi=2; break; - case 8: fi=3; break; - default: abort(); - } - - emit_byte(0x88); - emit_byte(0x84+8*s); - emit_byte(baser+8*index+0x40*fi); - emit_long(base); -} -LENDFUNC(NONE,WRITE,5,raw_mov_b_bmrr_indexed,(IMM base, R4 baser, R4 index, IMM factor, R1 s)) - -LOWFUNC(NONE,READ,5,raw_mov_l_brrm_indexed,(W4 d, IMM base, R4 baser, R4 index, IMM factor)) -{ - int fi; - - switch(factor) { - case 1: fi=0; break; - case 2: fi=1; break; - case 4: fi=2; break; - case 8: fi=3; break; - default: abort(); - } - - emit_byte(0x8b); - emit_byte(0x84+8*d); - emit_byte(baser+8*index+0x40*fi); - emit_long(base); -} -LENDFUNC(NONE,READ,5,raw_mov_l_brrm_indexed,(W4 d, IMM base, R4 baser, R4 index, IMM factor)) - -LOWFUNC(NONE,READ,5,raw_mov_w_brrm_indexed,(W2 d, IMM base, R4 baser, R4 index, IMM factor)) -{ - int fi; - - switch(factor) { - case 1: fi=0; break; - case 2: fi=1; break; - case 4: fi=2; break; - case 8: fi=3; break; - default: abort(); - } - - emit_byte(0x66); - emit_byte(0x8b); - emit_byte(0x84+8*d); - emit_byte(baser+8*index+0x40*fi); - emit_long(base); -} -LENDFUNC(NONE,READ,5,raw_mov_w_brrm_indexed,(W2 d, IMM base, R4 baser, R4 index, IMM factor)) - -LOWFUNC(NONE,READ,5,raw_mov_b_brrm_indexed,(W1 d, IMM base, R4 baser, R4 index, IMM factor)) -{ - int fi; - - switch(factor) { - case 1: fi=0; break; - case 2: fi=1; break; - case 4: fi=2; break; - case 8: fi=3; break; - default: abort(); - } - - emit_byte(0x8a); - emit_byte(0x84+8*d); - emit_byte(baser+8*index+0x40*fi); - emit_long(base); -} -LENDFUNC(NONE,READ,5,raw_mov_b_brrm_indexed,(W1 d, IMM base, R4 baser, R4 index, IMM factor)) - -LOWFUNC(NONE,READ,4,raw_mov_l_rm_indexed,(W4 d, IMM base, R4 index, IMM factor)) -{ - int fi; - switch(factor) { - case 1: fi=0; break; - case 2: fi=1; break; - case 4: fi=2; break; - case 8: fi=3; break; - default: - jit_abort("Bad factor %d in mov_l_rm_indexed!",factor); - } - emit_byte(0x8b); - emit_byte(0x04+8*d); - emit_byte(0x05+8*index+64*fi); - emit_long(base); -} -LENDFUNC(NONE,READ,4,raw_mov_l_rm_indexed,(W4 d, IMM base, R4 index, IMM factor)) - -LOWFUNC(NONE,READ,5,raw_cmov_l_rm_indexed,(W4 d, IMM base, R4 index, IMM factor, IMM cond)) -{ - int fi; - switch(factor) { - case 1: fi=0; break; - case 2: fi=1; break; - case 4: fi=2; break; - case 8: fi=3; break; - default: - jit_abort("Bad factor %d in mov_l_rm_indexed!",factor); - } - if (have_cmov) { - emit_byte(0x0f); - emit_byte(0x40+cond); - emit_byte(0x04+8*d); - emit_byte(0x05+8*index+64*fi); - emit_long(base); - } - else { /* replacement using branch and mov */ - int uncc=(cond^1); - emit_byte(0x70+uncc); - emit_byte(7); /* skip next 7 bytes if not cc=true */ - emit_byte(0x8b); - emit_byte(0x04+8*d); - emit_byte(0x05+8*index+64*fi); - emit_long(base); - } -} -LENDFUNC(NONE,READ,5,raw_cmov_l_rm_indexed,(W4 d, IMM base, R4 index, IMM factor, IMM cond)) - -LOWFUNC(NONE,READ,3,raw_cmov_l_rm,(W4 d, IMM mem, IMM cond)) -{ - if (have_cmov) { - emit_byte(0x0f); - emit_byte(0x40+cond); - emit_byte(0x05+8*d); - emit_long(mem); - } - else { /* replacement using branch and mov */ - int uncc=(cond^1); - emit_byte(0x70+uncc); - emit_byte(6); /* skip next 6 bytes if not cc=true */ - emit_byte(0x8b); - emit_byte(0x05+8*d); - emit_long(mem); - } -} -LENDFUNC(NONE,READ,3,raw_cmov_l_rm,(W4 d, IMM mem, IMM cond)) - -LOWFUNC(NONE,READ,3,raw_mov_l_rR,(W4 d, R4 s, IMM offset)) -{ - Dif(!isbyte(offset)) abort(); - emit_byte(0x8b); - emit_byte(0x40+8*d+s); - emit_byte(offset); -} -LENDFUNC(NONE,READ,3,raw_mov_l_rR,(W4 d, R4 s, IMM offset)) - -LOWFUNC(NONE,READ,3,raw_mov_w_rR,(W2 d, R4 s, IMM offset)) -{ - Dif(!isbyte(offset)) abort(); - emit_byte(0x66); - emit_byte(0x8b); - emit_byte(0x40+8*d+s); - emit_byte(offset); -} -LENDFUNC(NONE,READ,3,raw_mov_w_rR,(W2 d, R4 s, IMM offset)) - -LOWFUNC(NONE,READ,3,raw_mov_b_rR,(W1 d, R4 s, IMM offset)) -{ - Dif(!isbyte(offset)) abort(); - emit_byte(0x8a); - emit_byte(0x40+8*d+s); - emit_byte(offset); -} -LENDFUNC(NONE,READ,3,raw_mov_b_rR,(W1 d, R4 s, IMM offset)) - -LOWFUNC(NONE,READ,3,raw_mov_l_brR,(W4 d, R4 s, IMM offset)) -{ - emit_byte(0x8b); - emit_byte(0x80+8*d+s); - emit_long(offset); -} -LENDFUNC(NONE,READ,3,raw_mov_l_brR,(W4 d, R4 s, IMM offset)) - -LOWFUNC(NONE,READ,3,raw_mov_w_brR,(W2 d, R4 s, IMM offset)) -{ - emit_byte(0x66); - emit_byte(0x8b); - emit_byte(0x80+8*d+s); - emit_long(offset); -} -LENDFUNC(NONE,READ,3,raw_mov_w_brR,(W2 d, R4 s, IMM offset)) - -LOWFUNC(NONE,READ,3,raw_mov_b_brR,(W1 d, R4 s, IMM offset)) -{ - emit_byte(0x8a); - emit_byte(0x80+8*d+s); - emit_long(offset); -} -LENDFUNC(NONE,READ,3,raw_mov_b_brR,(W1 d, R4 s, IMM offset)) - -LOWFUNC(NONE,WRITE,3,raw_mov_l_Ri,(R4 d, IMM i, IMM offset)) -{ - Dif(!isbyte(offset)) abort(); - emit_byte(0xc7); - emit_byte(0x40+d); - emit_byte(offset); - emit_long(i); -} -LENDFUNC(NONE,WRITE,3,raw_mov_l_Ri,(R4 d, IMM i, IMM offset)) - -LOWFUNC(NONE,WRITE,3,raw_mov_w_Ri,(R4 d, IMM i, IMM offset)) -{ - Dif(!isbyte(offset)) abort(); - emit_byte(0x66); - emit_byte(0xc7); - emit_byte(0x40+d); - emit_byte(offset); - emit_word(i); -} -LENDFUNC(NONE,WRITE,3,raw_mov_w_Ri,(R4 d, IMM i, IMM offset)) - -LOWFUNC(NONE,WRITE,3,raw_mov_b_Ri,(R4 d, IMM i, IMM offset)) -{ - Dif(!isbyte(offset)) abort(); - emit_byte(0xc6); - emit_byte(0x40+d); - emit_byte(offset); - emit_byte(i); -} -LENDFUNC(NONE,WRITE,3,raw_mov_b_Ri,(R4 d, IMM i, IMM offset)) - -LOWFUNC(NONE,WRITE,3,raw_mov_l_Rr,(R4 d, R4 s, IMM offset)) -{ - Dif(!isbyte(offset)) abort(); - emit_byte(0x89); - emit_byte(0x40+8*s+d); - emit_byte(offset); -} -LENDFUNC(NONE,WRITE,3,raw_mov_l_Rr,(R4 d, R4 s, IMM offset)) - -LOWFUNC(NONE,WRITE,3,raw_mov_w_Rr,(R4 d, R2 s, IMM offset)) -{ - Dif(!isbyte(offset)) abort(); - emit_byte(0x66); - emit_byte(0x89); - emit_byte(0x40+8*s+d); - emit_byte(offset); -} -LENDFUNC(NONE,WRITE,3,raw_mov_w_Rr,(R4 d, R2 s, IMM offset)) - -LOWFUNC(NONE,WRITE,3,raw_mov_b_Rr,(R4 d, R1 s, IMM offset)) -{ - Dif(!isbyte(offset)) abort(); - emit_byte(0x88); - emit_byte(0x40+8*s+d); - emit_byte(offset); -} -LENDFUNC(NONE,WRITE,3,raw_mov_b_Rr,(R4 d, R1 s, IMM offset)) - -LOWFUNC(NONE,NONE,3,raw_lea_l_brr,(W4 d, R4 s, IMM offset)) -{ - if (optimize_imm8 && isbyte(offset)) { - emit_byte(0x8d); - emit_byte(0x40+8*d+s); - emit_byte(offset); - } - else { - emit_byte(0x8d); - emit_byte(0x80+8*d+s); - emit_long(offset); - } -} -LENDFUNC(NONE,NONE,3,raw_lea_l_brr,(W4 d, R4 s, IMM offset)) - -LOWFUNC(NONE,NONE,5,raw_lea_l_brr_indexed,(W4 d, R4 s, R4 index, IMM factor, IMM offset)) -{ - int fi; - - switch(factor) { - case 1: fi=0; break; - case 2: fi=1; break; - case 4: fi=2; break; - case 8: fi=3; break; - default: abort(); - } - - if (optimize_imm8 && isbyte(offset)) { - emit_byte(0x8d); - emit_byte(0x44+8*d); - emit_byte(0x40*fi+8*index+s); - emit_byte(offset); - } - else { - emit_byte(0x8d); - emit_byte(0x84+8*d); - emit_byte(0x40*fi+8*index+s); - emit_long(offset); - } -} -LENDFUNC(NONE,NONE,5,raw_lea_l_brr_indexed,(W4 d, R4 s, R4 index, IMM factor, IMM offset)) - -LOWFUNC(NONE,NONE,4,raw_lea_l_rr_indexed,(W4 d, R4 s, R4 index, IMM factor)) -{ - int isebp=(s==5)?0x40:0; - int fi; - - switch(factor) { - case 1: fi=0; break; - case 2: fi=1; break; - case 4: fi=2; break; - case 8: fi=3; break; - default: abort(); - } - - emit_byte(0x8d); - emit_byte(0x04+8*d+isebp); - emit_byte(0x40*fi+8*index+s); - if (isebp) - emit_byte(0); -} -LENDFUNC(NONE,NONE,4,raw_lea_l_rr_indexed,(W4 d, R4 s, R4 index, IMM factor)) - -LOWFUNC(NONE,WRITE,3,raw_mov_l_bRr,(R4 d, R4 s, IMM offset)) -{ - if (optimize_imm8 && isbyte(offset)) { - emit_byte(0x89); - emit_byte(0x40+8*s+d); - emit_byte(offset); - } - else { - emit_byte(0x89); - emit_byte(0x80+8*s+d); - emit_long(offset); - } +{ + ADDR32 MOVLrm(s, offset, d, X86_NOREG, 1); } -LENDFUNC(NONE,WRITE,3,raw_mov_l_bRr,(R4 d, R4 s, IMM offset)) LOWFUNC(NONE,WRITE,3,raw_mov_w_bRr,(R4 d, R2 s, IMM offset)) { - emit_byte(0x66); - emit_byte(0x89); - emit_byte(0x80+8*s+d); - emit_long(offset); + ADDR32 MOVWrm(s, offset, d, X86_NOREG, 1); } -LENDFUNC(NONE,WRITE,3,raw_mov_w_bRr,(R4 d, R2 s, IMM offset)) LOWFUNC(NONE,WRITE,3,raw_mov_b_bRr,(R4 d, R1 s, IMM offset)) { - if (optimize_imm8 && isbyte(offset)) { - emit_byte(0x88); - emit_byte(0x40+8*s+d); - emit_byte(offset); - } - else { - emit_byte(0x88); - emit_byte(0x80+8*s+d); - emit_long(offset); - } + ADDR32 MOVBrm(s, offset, d, X86_NOREG, 1); } -LENDFUNC(NONE,WRITE,3,raw_mov_b_bRr,(R4 d, R1 s, IMM offset)) LOWFUNC(NONE,NONE,1,raw_bswap_32,(RW4 r)) { - emit_byte(0x0f); - emit_byte(0xc8+r); + BSWAPLr(r); } -LENDFUNC(NONE,NONE,1,raw_bswap_32,(RW4 r)) LOWFUNC(WRITE,NONE,1,raw_bswap_16,(RW2 r)) { - emit_byte(0x66); - emit_byte(0xc1); - emit_byte(0xc0+r); - emit_byte(0x08); + ROLWir(8, r); } -LENDFUNC(WRITE,NONE,1,raw_bswap_16,(RW2 r)) LOWFUNC(NONE,NONE,2,raw_mov_l_rr,(W4 d, R4 s)) { - emit_byte(0x89); - emit_byte(0xc0+8*s+d); + MOVLrr(s, d); } -LENDFUNC(NONE,NONE,2,raw_mov_l_rr,(W4 d, R4 s)) LOWFUNC(NONE,WRITE,2,raw_mov_l_mr,(IMM d, R4 s)) { - emit_byte(0x89); - emit_byte(0x05+8*s); - emit_long(d); + ADDR32 MOVLrm(s, d, X86_NOREG, X86_NOREG, 1); } -LENDFUNC(NONE,WRITE,2,raw_mov_l_mr,(IMM d, R4 s)) LOWFUNC(NONE,WRITE,2,raw_mov_w_mr,(IMM d, R2 s)) { - emit_byte(0x66); - emit_byte(0x89); - emit_byte(0x05+8*s); - emit_long(d); + ADDR32 MOVWrm(s, d, X86_NOREG, X86_NOREG, 1); } -LENDFUNC(NONE,WRITE,2,raw_mov_w_mr,(IMM d, R2 s)) LOWFUNC(NONE,READ,2,raw_mov_w_rm,(W2 d, IMM s)) { - emit_byte(0x66); - emit_byte(0x8b); - emit_byte(0x05+8*d); - emit_long(s); + ADDR32 MOVWmr(s, X86_NOREG, X86_NOREG, 1, d); } -LENDFUNC(NONE,READ,2,raw_mov_w_rm,(W2 d, IMM s)) LOWFUNC(NONE,WRITE,2,raw_mov_b_mr,(IMM d, R1 s)) { - emit_byte(0x88); - emit_byte(0x05+8*(s&0xf)); /* XXX this handles %ah case (defined as 0x10+4) and others */ - emit_long(d); + ADDR32 MOVBrm(s, d, X86_NOREG, X86_NOREG, 1); } -LENDFUNC(NONE,WRITE,2,raw_mov_b_mr,(IMM d, R1 s)) LOWFUNC(NONE,READ,2,raw_mov_b_rm,(W1 d, IMM s)) { - emit_byte(0x8a); - emit_byte(0x05+8*d); - emit_long(s); + ADDR32 MOVBmr(s, X86_NOREG, X86_NOREG, 1, d); } -LENDFUNC(NONE,READ,2,raw_mov_b_rm,(W1 d, IMM s)) LOWFUNC(NONE,NONE,2,raw_mov_l_ri,(W4 d, IMM s)) { - emit_byte(0xb8+d); - emit_long(s); + MOVLir(s, d); } -LENDFUNC(NONE,NONE,2,raw_mov_l_ri,(W4 d, IMM s)) LOWFUNC(NONE,NONE,2,raw_mov_w_ri,(W2 d, IMM s)) { - emit_byte(0x66); - emit_byte(0xb8+d); - emit_word(s); + MOVWir(s, d); } -LENDFUNC(NONE,NONE,2,raw_mov_w_ri,(W2 d, IMM s)) LOWFUNC(NONE,NONE,2,raw_mov_b_ri,(W1 d, IMM s)) { - emit_byte(0xb0+d); - emit_byte(s); + MOVBir(s, d); } -LENDFUNC(NONE,NONE,2,raw_mov_b_ri,(W1 d, IMM s)) LOWFUNC(RMW,RMW,2,raw_adc_l_mi,(MEMRW d, IMM s)) { - emit_byte(0x81); - emit_byte(0x15); - emit_long(d); - emit_long(s); + ADDR32 ADCLim(s, d, X86_NOREG, X86_NOREG, 1); } -LENDFUNC(RMW,RMW,2,raw_adc_l_mi,(MEMRW d, IMM s)) -LOWFUNC(WRITE,RMW,2,raw_add_l_mi,(IMM d, IMM s)) +LOWFUNC(WRITE,RMW,2,raw_add_l_mi,(IMM d, IMM s)) { - if (optimize_imm8 && isbyte(s)) { - emit_byte(0x83); - emit_byte(0x05); - emit_long(d); - emit_byte(s); - } - else { - emit_byte(0x81); - emit_byte(0x05); - emit_long(d); - emit_long(s); - } + ADDR32 ADDLim(s, d, X86_NOREG, X86_NOREG, 1); } -LENDFUNC(WRITE,RMW,2,raw_add_l_mi,(IMM d, IMM s)) -LOWFUNC(WRITE,RMW,2,raw_add_w_mi,(IMM d, IMM s)) +LOWFUNC(WRITE,RMW,2,raw_add_w_mi,(IMM d, IMM s)) { - emit_byte(0x66); - emit_byte(0x81); - emit_byte(0x05); - emit_long(d); - emit_word(s); + ADDR32 ADDWim(s, d, X86_NOREG, X86_NOREG, 1); } -LENDFUNC(WRITE,RMW,2,raw_add_w_mi,(IMM d, IMM s)) -LOWFUNC(WRITE,RMW,2,raw_add_b_mi,(IMM d, IMM s)) +LOWFUNC(WRITE,RMW,2,raw_add_b_mi,(IMM d, IMM s)) { - emit_byte(0x80); - emit_byte(0x05); - emit_long(d); - emit_byte(s); + ADDR32 ADDBim(s, d, X86_NOREG, X86_NOREG, 1); } -LENDFUNC(WRITE,RMW,2,raw_add_b_mi,(IMM d, IMM s)) LOWFUNC(WRITE,NONE,2,raw_test_l_ri,(R4 d, IMM i)) { - if (optimize_accum && isaccum(d)) - emit_byte(0xa9); - else { - emit_byte(0xf7); - emit_byte(0xc0+d); - } - emit_long(i); + TESTLir(i, d); } -LENDFUNC(WRITE,NONE,2,raw_test_l_ri,(R4 d, IMM i)) LOWFUNC(WRITE,NONE,2,raw_test_l_rr,(R4 d, R4 s)) { - emit_byte(0x85); - emit_byte(0xc0+8*s+d); + TESTLrr(s, d); } -LENDFUNC(WRITE,NONE,2,raw_test_l_rr,(R4 d, R4 s)) LOWFUNC(WRITE,NONE,2,raw_test_w_rr,(R2 d, R2 s)) { - emit_byte(0x66); - emit_byte(0x85); - emit_byte(0xc0+8*s+d); + TESTWrr(s, d); } -LENDFUNC(WRITE,NONE,2,raw_test_w_rr,(R2 d, R2 s)) LOWFUNC(WRITE,NONE,2,raw_test_b_rr,(R1 d, R1 s)) { - emit_byte(0x84); - emit_byte(0xc0+8*s+d); + TESTBrr(s, d); +} + +LOWFUNC(WRITE,READ,2,raw_test_b_mi,(IMM d, IMM s)) +{ + ADDR32 TESTBim(s, d, X86_NOREG, X86_NOREG, 1); } -LENDFUNC(WRITE,NONE,2,raw_test_b_rr,(R1 d, R1 s)) LOWFUNC(WRITE,NONE,2,raw_xor_l_ri,(RW4 d, IMM i)) { - emit_byte(0x81); - emit_byte(0xf0+d); - emit_long(i); + XORLir(i, d); } -LENDFUNC(WRITE,NONE,2,raw_xor_l_ri,(RW4 d, IMM i)) LOWFUNC(WRITE,NONE,2,raw_and_l_ri,(RW4 d, IMM i)) { - if (optimize_imm8 && isbyte(i)) { - emit_byte(0x83); - emit_byte(0xe0+d); - emit_byte(i); - } - else { - if (optimize_accum && isaccum(d)) - emit_byte(0x25); - else { - emit_byte(0x81); - emit_byte(0xe0+d); - } - emit_long(i); - } + ANDLir(i, d); } -LENDFUNC(WRITE,NONE,2,raw_and_l_ri,(RW4 d, IMM i)) LOWFUNC(WRITE,NONE,2,raw_and_w_ri,(RW2 d, IMM i)) { - emit_byte(0x66); - if (optimize_imm8 && isbyte(i)) { - emit_byte(0x83); - emit_byte(0xe0+d); - emit_byte(i); - } - else { - if (optimize_accum && isaccum(d)) - emit_byte(0x25); - else { - emit_byte(0x81); - emit_byte(0xe0+d); - } - emit_word(i); - } + ANDWir(i, d); } -LENDFUNC(WRITE,NONE,2,raw_and_w_ri,(RW2 d, IMM i)) LOWFUNC(WRITE,NONE,2,raw_and_l,(RW4 d, R4 s)) { - emit_byte(0x21); - emit_byte(0xc0+8*s+d); + ANDLrr(s, d); } -LENDFUNC(WRITE,NONE,2,raw_and_l,(RW4 d, R4 s)) LOWFUNC(WRITE,NONE,2,raw_and_w,(RW2 d, R2 s)) { - emit_byte(0x66); - emit_byte(0x21); - emit_byte(0xc0+8*s+d); + ANDWrr(s, d); } -LENDFUNC(WRITE,NONE,2,raw_and_w,(RW2 d, R2 s)) LOWFUNC(WRITE,NONE,2,raw_and_b,(RW1 d, R1 s)) { - emit_byte(0x20); - emit_byte(0xc0+8*s+d); + ANDBrr(s, d); } -LENDFUNC(WRITE,NONE,2,raw_and_b,(RW1 d, R1 s)) LOWFUNC(WRITE,NONE,2,raw_or_l_ri,(RW4 d, IMM i)) { - if (optimize_imm8 && isbyte(i)) { - emit_byte(0x83); - emit_byte(0xc8+d); - emit_byte(i); - } - else { - if (optimize_accum && isaccum(d)) - emit_byte(0x0d); - else { - emit_byte(0x81); - emit_byte(0xc8+d); - } - emit_long(i); - } + ORLir(i, d); } -LENDFUNC(WRITE,NONE,2,raw_or_l_ri,(RW4 d, IMM i)) LOWFUNC(WRITE,NONE,2,raw_or_l,(RW4 d, R4 s)) { - emit_byte(0x09); - emit_byte(0xc0+8*s+d); + ORLrr(s, d); } -LENDFUNC(WRITE,NONE,2,raw_or_l,(RW4 d, R4 s)) LOWFUNC(WRITE,NONE,2,raw_or_w,(RW2 d, R2 s)) { - emit_byte(0x66); - emit_byte(0x09); - emit_byte(0xc0+8*s+d); + ORWrr(s, d); } -LENDFUNC(WRITE,NONE,2,raw_or_w,(RW2 d, R2 s)) LOWFUNC(WRITE,NONE,2,raw_or_b,(RW1 d, R1 s)) { - emit_byte(0x08); - emit_byte(0xc0+8*s+d); + ORBrr(s, d); } -LENDFUNC(WRITE,NONE,2,raw_or_b,(RW1 d, R1 s)) LOWFUNC(RMW,NONE,2,raw_adc_l,(RW4 d, R4 s)) { - emit_byte(0x11); - emit_byte(0xc0+8*s+d); + ADCLrr(s, d); } -LENDFUNC(RMW,NONE,2,raw_adc_l,(RW4 d, R4 s)) LOWFUNC(RMW,NONE,2,raw_adc_w,(RW2 d, R2 s)) { - emit_byte(0x66); - emit_byte(0x11); - emit_byte(0xc0+8*s+d); + ADCWrr(s, d); } -LENDFUNC(RMW,NONE,2,raw_adc_w,(RW2 d, R2 s)) LOWFUNC(RMW,NONE,2,raw_adc_b,(RW1 d, R1 s)) { - emit_byte(0x10); - emit_byte(0xc0+8*s+d); + ADCBrr(s, d); } -LENDFUNC(RMW,NONE,2,raw_adc_b,(RW1 d, R1 s)) LOWFUNC(WRITE,NONE,2,raw_add_l,(RW4 d, R4 s)) { - emit_byte(0x01); - emit_byte(0xc0+8*s+d); + ADDLrr(s, d); } -LENDFUNC(WRITE,NONE,2,raw_add_l,(RW4 d, R4 s)) LOWFUNC(WRITE,NONE,2,raw_add_w,(RW2 d, R2 s)) { - emit_byte(0x66); - emit_byte(0x01); - emit_byte(0xc0+8*s+d); + ADDWrr(s, d); } -LENDFUNC(WRITE,NONE,2,raw_add_w,(RW2 d, R2 s)) LOWFUNC(WRITE,NONE,2,raw_add_b,(RW1 d, R1 s)) { - emit_byte(0x00); - emit_byte(0xc0+8*s+d); + ADDBrr(s, d); } -LENDFUNC(WRITE,NONE,2,raw_add_b,(RW1 d, R1 s)) LOWFUNC(WRITE,NONE,2,raw_sub_l_ri,(RW4 d, IMM i)) { - if (isbyte(i)) { - emit_byte(0x83); - emit_byte(0xe8+d); - emit_byte(i); - } - else { - if (optimize_accum && isaccum(d)) - emit_byte(0x2d); - else { - emit_byte(0x81); - emit_byte(0xe8+d); - } - emit_long(i); - } + SUBLir(i, d); } -LENDFUNC(WRITE,NONE,2,raw_sub_l_ri,(RW4 d, IMM i)) LOWFUNC(WRITE,NONE,2,raw_sub_b_ri,(RW1 d, IMM i)) { - if (optimize_accum && isaccum(d)) - emit_byte(0x2c); - else { - emit_byte(0x80); - emit_byte(0xe8+d); - } - emit_byte(i); + SUBBir(i, d); } -LENDFUNC(WRITE,NONE,2,raw_sub_b_ri,(RW1 d, IMM i)) LOWFUNC(WRITE,NONE,2,raw_add_l_ri,(RW4 d, IMM i)) { - if (isbyte(i)) { - emit_byte(0x83); - emit_byte(0xc0+d); - emit_byte(i); - } - else { - if (optimize_accum && isaccum(d)) - emit_byte(0x05); - else { - emit_byte(0x81); - emit_byte(0xc0+d); - } - emit_long(i); - } + ADDLir(i, d); } -LENDFUNC(WRITE,NONE,2,raw_add_l_ri,(RW4 d, IMM i)) LOWFUNC(WRITE,NONE,2,raw_add_w_ri,(RW2 d, IMM i)) { - emit_byte(0x66); - if (isbyte(i)) { - emit_byte(0x83); - emit_byte(0xc0+d); - emit_byte(i); - } - else { - if (optimize_accum && isaccum(d)) - emit_byte(0x05); - else { - emit_byte(0x81); - emit_byte(0xc0+d); - } - emit_word(i); - } + ADDWir(i, d); } -LENDFUNC(WRITE,NONE,2,raw_add_w_ri,(RW2 d, IMM i)) LOWFUNC(WRITE,NONE,2,raw_add_b_ri,(RW1 d, IMM i)) { - if (optimize_accum && isaccum(d)) - emit_byte(0x04); - else { - emit_byte(0x80); - emit_byte(0xc0+d); - } - emit_byte(i); + ADDBir(i, d); } -LENDFUNC(WRITE,NONE,2,raw_add_b_ri,(RW1 d, IMM i)) LOWFUNC(RMW,NONE,2,raw_sbb_l,(RW4 d, R4 s)) { - emit_byte(0x19); - emit_byte(0xc0+8*s+d); + SBBLrr(s, d); } -LENDFUNC(RMW,NONE,2,raw_sbb_l,(RW4 d, R4 s)) LOWFUNC(RMW,NONE,2,raw_sbb_w,(RW2 d, R2 s)) { - emit_byte(0x66); - emit_byte(0x19); - emit_byte(0xc0+8*s+d); + SBBWrr(s, d); } -LENDFUNC(RMW,NONE,2,raw_sbb_w,(RW2 d, R2 s)) LOWFUNC(RMW,NONE,2,raw_sbb_b,(RW1 d, R1 s)) { - emit_byte(0x18); - emit_byte(0xc0+8*s+d); + SBBBrr(s, d); } -LENDFUNC(RMW,NONE,2,raw_sbb_b,(RW1 d, R1 s)) LOWFUNC(WRITE,NONE,2,raw_sub_l,(RW4 d, R4 s)) { - emit_byte(0x29); - emit_byte(0xc0+8*s+d); + SUBLrr(s, d); } -LENDFUNC(WRITE,NONE,2,raw_sub_l,(RW4 d, R4 s)) LOWFUNC(WRITE,NONE,2,raw_sub_w,(RW2 d, R2 s)) { - emit_byte(0x66); - emit_byte(0x29); - emit_byte(0xc0+8*s+d); + SUBWrr(s, d); } -LENDFUNC(WRITE,NONE,2,raw_sub_w,(RW2 d, R2 s)) LOWFUNC(WRITE,NONE,2,raw_sub_b,(RW1 d, R1 s)) { - emit_byte(0x28); - emit_byte(0xc0+8*s+d); + SUBBrr(s, d); } -LENDFUNC(WRITE,NONE,2,raw_sub_b,(RW1 d, R1 s)) LOWFUNC(WRITE,NONE,2,raw_cmp_l,(R4 d, R4 s)) { - emit_byte(0x39); - emit_byte(0xc0+8*s+d); + CMPLrr(s, d); } -LENDFUNC(WRITE,NONE,2,raw_cmp_l,(R4 d, R4 s)) LOWFUNC(WRITE,NONE,2,raw_cmp_l_ri,(R4 r, IMM i)) { - if (optimize_imm8 && isbyte(i)) { - emit_byte(0x83); - emit_byte(0xf8+r); - emit_byte(i); - } - else { - if (optimize_accum && isaccum(r)) - emit_byte(0x3d); - else { - emit_byte(0x81); - emit_byte(0xf8+r); - } - emit_long(i); - } + CMPLir(i, r); } -LENDFUNC(WRITE,NONE,2,raw_cmp_l_ri,(R4 r, IMM i)) LOWFUNC(WRITE,NONE,2,raw_cmp_w,(R2 d, R2 s)) { - emit_byte(0x66); - emit_byte(0x39); - emit_byte(0xc0+8*s+d); + CMPWrr(s, d); } -LENDFUNC(WRITE,NONE,2,raw_cmp_w,(R2 d, R2 s)) LOWFUNC(WRITE,READ,2,raw_cmp_b_mi,(MEMR d, IMM s)) { - emit_byte(0x80); - emit_byte(0x3d); - emit_long(d); - emit_byte(s); + ADDR32 CMPBim(s, d, X86_NOREG, X86_NOREG, 1); } -LENDFUNC(WRITE,READ,2,raw_cmp_l_mi,(MEMR d, IMM s)) LOWFUNC(WRITE,NONE,2,raw_cmp_b_ri,(R1 d, IMM i)) { - if (optimize_accum && isaccum(d)) - emit_byte(0x3c); - else { - emit_byte(0x80); - emit_byte(0xf8+d); - } - emit_byte(i); + CMPBir(i, d); } -LENDFUNC(WRITE,NONE,2,raw_cmp_b_ri,(R1 d, IMM i)) LOWFUNC(WRITE,NONE,2,raw_cmp_b,(R1 d, R1 s)) { - emit_byte(0x38); - emit_byte(0xc0+8*s+d); + CMPBrr(s, d); } -LENDFUNC(WRITE,NONE,2,raw_cmp_b,(R1 d, R1 s)) LOWFUNC(WRITE,READ,4,raw_cmp_l_rm_indexed,(R4 d, IMM offset, R4 index, IMM factor)) { - int fi; - - switch(factor) { - case 1: fi=0; break; - case 2: fi=1; break; - case 4: fi=2; break; - case 8: fi=3; break; - default: abort(); - } - emit_byte(0x39); - emit_byte(0x04+8*d); - emit_byte(5+8*index+0x40*fi); - emit_long(offset); + ADDR32 CMPLmr(offset, X86_NOREG, index, factor, d); } -LENDFUNC(WRITE,READ,4,raw_cmp_l_rm_indexed,(R4 d, IMM offset, R4 index, IMM factor)) LOWFUNC(WRITE,NONE,2,raw_xor_l,(RW4 d, R4 s)) { - emit_byte(0x31); - emit_byte(0xc0+8*s+d); + XORLrr(s, d); } -LENDFUNC(WRITE,NONE,2,raw_xor_l,(RW4 d, R4 s)) LOWFUNC(WRITE,NONE,2,raw_xor_w,(RW2 d, R2 s)) { - emit_byte(0x66); - emit_byte(0x31); - emit_byte(0xc0+8*s+d); + XORWrr(s, d); } -LENDFUNC(WRITE,NONE,2,raw_xor_w,(RW2 d, R2 s)) LOWFUNC(WRITE,NONE,2,raw_xor_b,(RW1 d, R1 s)) { - emit_byte(0x30); - emit_byte(0xc0+8*s+d); + XORBrr(s, d); } -LENDFUNC(WRITE,NONE,2,raw_xor_b,(RW1 d, R1 s)) LOWFUNC(WRITE,RMW,2,raw_sub_l_mi,(MEMRW d, IMM s)) { - if (optimize_imm8 && isbyte(s)) { - emit_byte(0x83); - emit_byte(0x2d); - emit_long(d); - emit_byte(s); - } - else { - emit_byte(0x81); - emit_byte(0x2d); - emit_long(d); - emit_long(s); - } + ADDR32 SUBLim(s, d, X86_NOREG, X86_NOREG, 1); } -LENDFUNC(WRITE,RMW,2,raw_sub_l_mi,(MEMRW d, IMM s)) LOWFUNC(WRITE,READ,2,raw_cmp_l_mi,(MEMR d, IMM s)) { - if (optimize_imm8 && isbyte(s)) { - emit_byte(0x83); - emit_byte(0x3d); - emit_long(d); - emit_byte(s); - } - else { - emit_byte(0x81); - emit_byte(0x3d); - emit_long(d); - emit_long(s); - } + ADDR32 CMPLim(s, d, X86_NOREG, X86_NOREG, 1); } -LENDFUNC(WRITE,READ,2,raw_cmp_l_mi,(MEMR d, IMM s)) LOWFUNC(NONE,NONE,2,raw_xchg_l_rr,(RW4 r1, RW4 r2)) { - emit_byte(0x87); - emit_byte(0xc0+8*r1+r2); + XCHGLrr(r2, r1); } -LENDFUNC(NONE,NONE,2,raw_xchg_l_rr,(RW4 r1, RW4 r2)) LOWFUNC(NONE,NONE,2,raw_xchg_b_rr,(RW4 r1, RW4 r2)) { - emit_byte(0x86); - emit_byte(0xc0+8*(r1&0xf)+(r2&0xf)); /* XXX this handles upper-halves registers (e.g. %ah defined as 0x10+4) */ + XCHGBrr(r2, r1); } -LENDFUNC(NONE,NONE,2,raw_xchg_l_rr,(RW4 r1, RW4 r2)) - -/************************************************************************* - * FIXME: mem access modes probably wrong * - *************************************************************************/ LOWFUNC(READ,WRITE,0,raw_pushfl,(void)) { - emit_byte(0x9c); + PUSHF(); } -LENDFUNC(READ,WRITE,0,raw_pushfl,(void)) LOWFUNC(WRITE,READ,0,raw_popfl,(void)) { - emit_byte(0x9d); + POPF(); } -LENDFUNC(WRITE,READ,0,raw_popfl,(void)) /* Generate floating-point instructions */ static inline void x86_fadd_m(MEMR s) { - emit_byte(0xdc); - emit_byte(0x05); - emit_long(s); + ADDR32 FADDLm(s,X86_NOREG,X86_NOREG,1); } -#endif /* USE_NEW_RTASM */ /************************************************************************* * Unoptimizable stuff --- jump * @@ -3106,62 +1155,22 @@ static inline void x86_fadd_m(MEMR s) static inline void raw_call_r(R4 r) { -#if USE_NEW_RTASM CALLsr(r); -#else - emit_byte(0xff); - emit_byte(0xd0+r); -#endif } static inline void raw_call_m_indexed(uae_u32 base, uae_u32 r, uae_u32 m) { -#if USE_NEW_RTASM ADDR32 CALLsm(base, X86_NOREG, r, m); -#else - int mu; - switch(m) { - case 1: mu=0; break; - case 2: mu=1; break; - case 4: mu=2; break; - case 8: mu=3; break; - default: abort(); - } - emit_byte(0xff); - emit_byte(0x14); - emit_byte(0x05+8*r+0x40*mu); - emit_long(base); -#endif } static inline void raw_jmp_r(R4 r) { -#if USE_NEW_RTASM JMPsr(r); -#else - emit_byte(0xff); - emit_byte(0xe0+r); -#endif } static inline void raw_jmp_m_indexed(uae_u32 base, uae_u32 r, uae_u32 m) { -#if USE_NEW_RTASM ADDR32 JMPsm(base, X86_NOREG, r, m); -#else - int mu; - switch (m) { - case 1: mu=0; break; - case 2: mu=1; break; - case 4: mu=2; break; - case 8: mu=3; break; - default: abort(); - } - emit_byte(0xff); - emit_byte(0x24); - emit_byte(0x05+8*r+0x40*mu); - emit_long(base); -#endif } static inline void raw_jmp_m(uae_u32 base) @@ -3174,70 +1183,61 @@ static inline void raw_jmp_m(uae_u32 base) static inline void raw_call(uae_u32 t) { -#if USE_NEW_RTASM ADDR32 CALLm(t); -#else - emit_byte(0xe8); - emit_long(t-(uintptr)target-4); -#endif } static inline void raw_jmp(uae_u32 t) { -#if USE_NEW_RTASM ADDR32 JMPm(t); -#else - emit_byte(0xe9); - emit_long(t-(uintptr)target-4); -#endif } -static inline void raw_jl(uae_u32 t) +static inline void raw_jcc_l_oponly(int cc) { emit_byte(0x0f); - emit_byte(0x8c); - emit_long(t-(uintptr)target-4); + emit_byte(0x80+cc); } -static inline void raw_jz(uae_u32 t) +static inline void raw_jz_l_oponly(void) { - emit_byte(0x0f); - emit_byte(0x84); - emit_long(t-(uintptr)target-4); + raw_jcc_l_oponly(NATIVE_CC_EQ); } -static inline void raw_jnz(uae_u32 t) +static inline void raw_jnz_l_oponly(void) { - emit_byte(0x0f); - emit_byte(0x85); + raw_jcc_l_oponly(NATIVE_CC_NE); +} + +static inline void raw_jl(uae_u32 t) +{ + raw_jcc_l_oponly(NATIVE_CC_LT); emit_long(t-(uintptr)target-4); } -static inline void raw_jnz_l_oponly(void) +static inline void raw_jz(uae_u32 t) { - emit_byte(0x0f); - emit_byte(0x85); + raw_jz_l_oponly(); + emit_long(t-(uintptr)target-4); } -static inline void raw_jcc_l_oponly(int cc) +static inline void raw_jnz(uae_u32 t) { - emit_byte(0x0f); - emit_byte(0x80+cc); + raw_jnz_l_oponly(); + emit_long(t-(uintptr)target-4); } -static inline void raw_jnz_b_oponly(void) +static inline void raw_jcc_b_oponly(int cc) { - emit_byte(0x75); + emit_byte(0x70+cc); } -static inline void raw_jz_b_oponly(void) +static inline void raw_jnz_b_oponly(void) { - emit_byte(0x74); + raw_jcc_b_oponly(NATIVE_CC_NE); } -static inline void raw_jcc_b_oponly(int cc) +static inline void raw_jz_b_oponly(void) { - emit_byte(0x70+cc); + raw_jcc_b_oponly(NATIVE_CC_EQ); } static inline void raw_jmp_l_oponly(void) @@ -3363,7 +1363,7 @@ static inline void raw_flags_evicted(int r) live.nat[r].nholds=0; } -#define FLAG_NREG1_FLAGREG 0 /* Set to -1 if any register will do */ +#define FLAG_NREG1_FLAGREG EAX_INDEX /* Set to -1 if any register will do */ static inline void raw_flags_to_reg_FLAGREG(int r) { raw_lahf(0); /* Most flags in AH */ @@ -3377,14 +1377,14 @@ static inline void raw_flags_to_reg_FLAGREG(int r) #endif } -#define FLAG_NREG2_FLAGREG 0 /* Set to -1 if any register will do */ +#define FLAG_NREG2_FLAGREG EAX_INDEX /* Set to -1 if any register will do */ static inline void raw_reg_to_flags_FLAGREG(int r) { raw_cmp_b_ri(r,-127); /* set V */ raw_sahf(0); } -#define FLAG_NREG3_FLAGREG 0 /* Set to -1 if any register will do */ +#define FLAG_NREG3_FLAGREG EAX_INDEX /* Set to -1 if any register will do */ static __inline__ void raw_flags_set_zero_FLAGREG(int s, int tmp) { raw_mov_l_rr(tmp,s); @@ -3436,7 +1436,7 @@ static inline void raw_flags_init_FLAGSTK(void) { } /* Try to use the LAHF/SETO method on x86_64 since it is faster. This can't be the default because some older CPUs don't support LAHF/SAHF in long mode. */ -static int FLAG_NREG1_FLAGGEN = 0; +static int FLAG_NREG1_FLAGGEN = EAX_INDEX; static inline void raw_flags_to_reg_FLAGGEN(int r) { if (have_lahf_lm) { @@ -3455,7 +1455,7 @@ static inline void raw_flags_to_reg_FLAGGEN(int r) raw_flags_to_reg_FLAGSTK(r); } -static int FLAG_NREG2_FLAGGEN = 0; +static int FLAG_NREG2_FLAGGEN = EAX_INDEX; static inline void raw_reg_to_flags_FLAGGEN(int r) { if (have_lahf_lm) { @@ -3467,7 +1467,7 @@ static inline void raw_reg_to_flags_FLAGGEN(int r) raw_reg_to_flags_FLAGSTK(r); } -static int FLAG_NREG3_FLAGGEN = 0; +static int FLAG_NREG3_FLAGGEN = EAX_INDEX; static inline void raw_flags_set_zero_FLAGGEN(int s, int tmp) { if (have_lahf_lm) @@ -3481,12 +1481,12 @@ static inline void raw_flags_init_FLAGGEN(void) if (have_lahf_lm) { FLAG_NREG1_FLAGGEN = FLAG_NREG1_FLAGREG; FLAG_NREG2_FLAGGEN = FLAG_NREG2_FLAGREG; - FLAG_NREG1_FLAGGEN = FLAG_NREG3_FLAGREG; + FLAG_NREG3_FLAGGEN = FLAG_NREG3_FLAGREG; } else { FLAG_NREG1_FLAGGEN = FLAG_NREG1_FLAGSTK; FLAG_NREG2_FLAGGEN = FLAG_NREG2_FLAGSTK; - FLAG_NREG1_FLAGGEN = FLAG_NREG3_FLAGSTK; + FLAG_NREG3_FLAGGEN = FLAG_NREG3_FLAGSTK; } } #endif @@ -3513,33 +1513,23 @@ static inline void raw_flags_init_FLAGGEN(void) /* Apparently, there are enough instructions between flag store and flag reload to avoid the partial memory stall */ -static inline void raw_load_flagreg(uae_u32 target, uae_u32 r) +static inline void raw_load_flagreg(uae_u32 target) { -#if 1 - raw_mov_l_rm(target,(uintptr)live.state[r].mem); -#else - raw_mov_b_rm(target,(uintptr)live.state[r].mem); - raw_mov_b_rm(target+4,((uintptr)live.state[r].mem)+1); -#endif + /* attention: in 64bit mode, relies on LITTE_ENDIANESS of regflags.cznv */ + raw_mov_l_rm(target,(uintptr)live.state[FLAGTMP].mem); } -#ifdef UAE -/* FLAGX is word-sized */ -#else -/* FLAGX is byte sized, and we *do* write it at that size */ -#endif -static inline void raw_load_flagx(uae_u32 target, uae_u32 r) +static inline void raw_load_flagx(uae_u32 target) { -#ifdef UAE - if (live.nat[target].canword) -#else +#if FLAGBIT_X < 8 if (live.nat[target].canbyte) - raw_mov_b_rm(target,(uintptr)live.state[r].mem); - else if (live.nat[target].canword) + raw_mov_b_rm(target,(uintptr)live.state[FLAGX].mem); + else #endif - raw_mov_w_rm(target,(uintptr)live.state[r].mem); + if (live.nat[target].canword) + raw_mov_w_rm(target,(uintptr)live.state[FLAGX].mem); else - raw_mov_l_rm(target,(uintptr)live.state[r].mem); + raw_mov_l_rm(target,(uintptr)live.state[FLAGX].mem); } static inline void raw_dec_sp(int off) @@ -4054,9 +2044,8 @@ static inline void tos_make(int r) } /* FP helper functions */ -#if USE_NEW_RTASM #define DEFINE_OP(NAME, GEN) \ -static inline void raw_##NAME(uint32 m) \ +static inline void raw_##NAME(uintptr m) \ { \ GEN(m, X86_NOREG, X86_NOREG, 1); \ } @@ -4070,35 +2059,15 @@ DEFINE_OP(fsts, FSTSm); DEFINE_OP(fstpt, FSTPTm); DEFINE_OP(fldt, FLDTm); DEFINE_OP(fistpl, FISTPLm); -#else -#define DEFINE_OP(NAME, OP1, OP2) \ -static inline void raw_##NAME(uint32 m) \ -{ \ - emit_byte(OP1); \ - emit_byte(OP2); \ - emit_long(m); \ -} -DEFINE_OP(fstl, 0xdd, 0x15); -DEFINE_OP(fstpl, 0xdd, 0x1d); -DEFINE_OP(fldl, 0xdd, 0x05); -DEFINE_OP(fildl, 0xdb, 0x05); -DEFINE_OP(fistl, 0xdb, 0x15); -DEFINE_OP(flds, 0xd9, 0x05); -DEFINE_OP(fsts, 0xd9, 0x15); -DEFINE_OP(fstpt, 0xdb, 0x3d); -DEFINE_OP(fldt, 0xdb, 0x2d); -DEFINE_OP(fistpl, 0xdb, 0x1d); -#endif #undef DEFINE_OP -LOWFUNC(NONE,WRITE,2,raw_fmov_mr,(MEMW m, FR r)) +LOWFUNC(NONE,WRITE,2,raw_fmov_mr,(MEMPTRW m, FR r)) { make_tos(r); raw_fstl(m); } -LENDFUNC(NONE,WRITE,2,raw_fmov_mr,(MEMW m, FR r)) -LOWFUNC(NONE,WRITE,2,raw_fmov_mr_drop,(MEMW m, FR r)) +LOWFUNC(NONE,WRITE,2,raw_fmov_mr_drop,(MEMPTRW m, FR r)) { make_tos(r); raw_fstpl(m); @@ -4106,30 +2075,26 @@ LOWFUNC(NONE,WRITE,2,raw_fmov_mr_drop,(MEMW m, FR r)) live.tos--; live.spos[r]=-2; } -LENDFUNC(NONE,WRITE,2,raw_fmov_mr,(MEMW m, FR r)) -LOWFUNC(NONE,READ,2,raw_fmov_rm,(FW r, MEMR m)) +LOWFUNC(NONE,READ,2,raw_fmov_rm,(FW r, MEMPTRR m)) { raw_fldl(m); tos_make(r); } -LENDFUNC(NONE,READ,2,raw_fmov_rm,(FW r, MEMR m)) -LOWFUNC(NONE,READ,2,raw_fmovi_rm,(FW r, MEMR m)) +LOWFUNC(NONE,READ,2,raw_fmovi_rm,(FW r, MEMPTRR m)) { raw_fildl(m); tos_make(r); } -LENDFUNC(NONE,READ,2,raw_fmovi_rm,(FW r, MEMR m)) -LOWFUNC(NONE,WRITE,2,raw_fmovi_mr,(MEMW m, FR r)) +LOWFUNC(NONE,WRITE,2,raw_fmovi_mr,(MEMPTRW m, FR r)) { make_tos(r); raw_fistl(m); } -LENDFUNC(NONE,WRITE,2,raw_fmovi_mr,(MEMW m, FR r)) -LOWFUNC(NONE,WRITE,3,raw_fmovi_mrb,(MEMW m, FR r, double *bounds)) +LOWFUNC(NONE,WRITE,3,raw_fmovi_mrb,(MEMPTRW m, FR r, double *bounds)) { /* Clamp value to the given range and convert to integer. */ @@ -4160,23 +2125,20 @@ LOWFUNC(NONE,WRITE,3,raw_fmovi_mrb,(MEMW m, FR r, double *bounds)) /* Store to destination */ raw_fistpl(m); } -LENDFUNC(NONE,WRITE,3,raw_fmovi_mrb,(MEMW m, FR r, double *bounds)) -LOWFUNC(NONE,READ,2,raw_fmovs_rm,(FW r, MEMR m)) +LOWFUNC(NONE,READ,2,raw_fmovs_rm,(FW r, MEMPTRR m)) { raw_flds(m); tos_make(r); } -LENDFUNC(NONE,READ,2,raw_fmovs_rm,(FW r, MEMR m)) -LOWFUNC(NONE,WRITE,2,raw_fmovs_mr,(MEMW m, FR r)) +LOWFUNC(NONE,WRITE,2,raw_fmovs_mr,(MEMPTRW m, FR r)) { make_tos(r); raw_fsts(m); } -LENDFUNC(NONE,WRITE,2,raw_fmovs_mr,(MEMW m, FR r)) -LOWFUNC(NONE,WRITE,2,raw_fmov_ext_mr,(MEMW m, FR r)) +LOWFUNC(NONE,WRITE,2,raw_fmov_ext_mr,(MEMPTRW m, FR r)) { int rs; @@ -4188,9 +2150,8 @@ LOWFUNC(NONE,WRITE,2,raw_fmov_ext_mr,(MEMW m, FR r)) raw_fstpt(m); /* store and pop it */ } -LENDFUNC(NONE,WRITE,2,raw_fmov_ext_mr,(MEMW m, FR r)) -LOWFUNC(NONE,WRITE,2,raw_fmov_ext_mr_drop,(MEMW m, FR r)) +LOWFUNC(NONE,WRITE,2,raw_fmov_ext_mr_drop,(MEMPTRW m, FR r)) { make_tos(r); raw_fstpt(m); /* store and pop it */ @@ -4198,14 +2159,12 @@ LOWFUNC(NONE,WRITE,2,raw_fmov_ext_mr_drop,(MEMW m, FR r)) live.tos--; live.spos[r]=-2; } -LENDFUNC(NONE,WRITE,2,raw_fmov_ext_mr,(MEMW m, FR r)) -LOWFUNC(NONE,READ,2,raw_fmov_ext_rm,(FW r, MEMR m)) +LOWFUNC(NONE,READ,2,raw_fmov_ext_rm,(FW r, MEMPTRR m)) { raw_fldt(m); tos_make(r); } -LENDFUNC(NONE,READ,2,raw_fmov_ext_rm,(FW r, MEMR m)) LOWFUNC(NONE,NONE,1,raw_fmov_pi,(FW r)) { @@ -4213,7 +2172,6 @@ LOWFUNC(NONE,NONE,1,raw_fmov_pi,(FW r)) emit_byte(0xeb); tos_make(r); } -LENDFUNC(NONE,NONE,1,raw_fmov_pi,(FW r)) LOWFUNC(NONE,NONE,1,raw_fmov_log10_2,(FW r)) { @@ -4221,7 +2179,6 @@ LOWFUNC(NONE,NONE,1,raw_fmov_log10_2,(FW r)) emit_byte(0xec); tos_make(r); } -LENDFUNC(NONE,NONE,1,raw_fmov_log10_2,(FW r)) LOWFUNC(NONE,NONE,1,raw_fmov_log2_e,(FW r)) { @@ -4229,7 +2186,6 @@ LOWFUNC(NONE,NONE,1,raw_fmov_log2_e,(FW r)) emit_byte(0xea); tos_make(r); } -LENDFUNC(NONE,NONE,1,raw_fmov_log2_e,(FW r)) LOWFUNC(NONE,NONE,1,raw_fmov_loge_2,(FW r)) { @@ -4237,7 +2193,6 @@ LOWFUNC(NONE,NONE,1,raw_fmov_loge_2,(FW r)) emit_byte(0xed); tos_make(r); } -LENDFUNC(NONE,NONE,1,raw_fmov_loge_2,(FW r)) LOWFUNC(NONE,NONE,1,raw_fmov_1,(FW r)) { @@ -4245,7 +2200,6 @@ LOWFUNC(NONE,NONE,1,raw_fmov_1,(FW r)) emit_byte(0xe8); tos_make(r); } -LENDFUNC(NONE,NONE,1,raw_fmov_1,(FW r)) LOWFUNC(NONE,NONE,1,raw_fmov_0,(FW r)) { @@ -4253,7 +2207,6 @@ LOWFUNC(NONE,NONE,1,raw_fmov_0,(FW r)) emit_byte(0xee); tos_make(r); } -LENDFUNC(NONE,NONE,1,raw_fmov_0,(FW r)) LOWFUNC(NONE,NONE,2,raw_fmov_rr,(FW d, FR s)) { @@ -4273,7 +2226,6 @@ LOWFUNC(NONE,NONE,2,raw_fmov_rr,(FW d, FR s)) tos_make(d); /* store to destination, pop if necessary */ } } -LENDFUNC(NONE,NONE,2,raw_fmov_rr,(FW d, FR s)) LOWFUNC(NONE,READ,2,raw_fldcw_m_indexed,(R4 index, IMM base)) { @@ -4282,7 +2234,6 @@ LOWFUNC(NONE,READ,2,raw_fldcw_m_indexed,(R4 index, IMM base)) emit_byte(0xa8 + index); emit_long(base); } -LENDFUNC(NONE,READ,2,raw_fldcw_m_indexed,(R4 index, IMM base)) LOWFUNC(NONE,NONE,2,raw_fsqrt_rr,(FW d, FR s)) { @@ -4303,7 +2254,6 @@ LOWFUNC(NONE,NONE,2,raw_fsqrt_rr,(FW d, FR s)) emit_byte(0xfa); /* take square root */ } } -LENDFUNC(NONE,NONE,2,raw_fsqrt_rr,(FW d, FR s)) LOWFUNC(NONE,NONE,2,raw_fabs_rr,(FW d, FR s)) { @@ -4324,7 +2274,6 @@ LOWFUNC(NONE,NONE,2,raw_fabs_rr,(FW d, FR s)) emit_byte(0xe1); /* take fabs */ } } -LENDFUNC(NONE,NONE,2,raw_fabs_rr,(FW d, FR s)) LOWFUNC(NONE,NONE,2,raw_frndint_rr,(FW d, FR s)) { @@ -4345,7 +2294,6 @@ LOWFUNC(NONE,NONE,2,raw_frndint_rr,(FW d, FR s)) emit_byte(0xfc); /* take frndint */ } } -LENDFUNC(NONE,NONE,2,raw_frndint_rr,(FW d, FR s)) LOWFUNC(NONE,NONE,2,raw_fcos_rr,(FW d, FR s)) { @@ -4366,7 +2314,6 @@ LOWFUNC(NONE,NONE,2,raw_fcos_rr,(FW d, FR s)) emit_byte(0xff); /* take cos */ } } -LENDFUNC(NONE,NONE,2,raw_fcos_rr,(FW d, FR s)) LOWFUNC(NONE,NONE,2,raw_fsin_rr,(FW d, FR s)) { @@ -4387,7 +2334,6 @@ LOWFUNC(NONE,NONE,2,raw_fsin_rr,(FW d, FR s)) emit_byte(0xfe); /* fsin y=sin(x) */ } } -LENDFUNC(NONE,NONE,2,raw_fsin_rr,(FW d, FR s)) static const double one = 1; @@ -4400,9 +2346,11 @@ LOWFUNC(NONE,NONE,2,raw_ftwotox_rr,(FW d, FR s)) emit_byte(0xd9); emit_byte(0xc0+ds); /* fld x */ emit_byte(0xd9); + emit_byte(0xc0); /* duplicate top of stack. Now up to 8 high */ + emit_byte(0xd9); emit_byte(0xfc); /* frndint int(x) */ emit_byte(0xd9); - emit_byte(0xc1+ds); /* fld x again */ + emit_byte(0xc9); /* swap top two elements */ emit_byte(0xd8); emit_byte(0xe1); /* fsub frac(x) = x - int(x) */ emit_byte(0xd9); @@ -4414,64 +2362,54 @@ LOWFUNC(NONE,NONE,2,raw_ftwotox_rr,(FW d, FR s)) emit_byte(0xd9); /* fstp copy & pop */ tos_make(d); /* store y=2^x */ } -LENDFUNC(NONE,NONE,2,raw_ftwotox_rr,(FW d, FR s)) LOWFUNC(NONE,NONE,2,raw_fetox_rr,(FW d, FR s)) { int ds; - if (s==d) - make_tos(s); - else { - ds=stackpos(s); - emit_byte(0xd9); - emit_byte(0xc0+ds); /* duplicate source */ - } + usereg(s); + ds=stackpos(s); + emit_byte(0xd9); + emit_byte(0xc0+ds); /* duplicate source */ emit_byte(0xd9); emit_byte(0xea); /* fldl2e log2(e) */ - emit_byte(0xd8); - emit_byte(0xc9); /* fmul x*log2(e) */ - emit_byte(0xdd); - emit_byte(0xd1); /* fst copy up */ + emit_byte(0xde); + emit_byte(0xc9); /* fmulp --- multiply source by log2(e) */ + emit_byte(0xd9); - emit_byte(0xfc); /* frndint int(x*log2(e)) */ + emit_byte(0xc0); /* duplicate top of stack. Now up to 8 high */ emit_byte(0xd9); - emit_byte(0xc9); /* fxch swap top two elements */ + emit_byte(0xfc); /* rndint */ + emit_byte(0xd9); + emit_byte(0xc9); /* swap top two elements */ emit_byte(0xd8); - emit_byte(0xe1); /* fsub x*log2(e) - int(x*log2(e)) */ + emit_byte(0xe1); /* subtract rounded from original */ emit_byte(0xd9); - emit_byte(0xf0); /* f2xm1 (2^frac(x))-1 */ - x86_fadd_m((uintptr) &one); /* Add '1' without using extra stack space */ + emit_byte(0xf0); /* f2xm1 */ + x86_fadd_m((uintptr)&one); /* Add '1' without using extra stack space */ emit_byte(0xd9); - emit_byte(0xfd); /* fscale (2^frac(x))*2^int(x*log2(e)) */ + emit_byte(0xfd); /* and scale it */ emit_byte(0xdd); - emit_byte(0xd9); /* fstp copy & pop */ - if (s!=d) - tos_make(d); /* store y=e^x */ + emit_byte(0xd9); /* take he rounded value off */ + tos_make(d); /* store to destination */ } -LENDFUNC(NONE,NONE,2,raw_fetox_rr,(FW d, FR s)) LOWFUNC(NONE,NONE,2,raw_flog2_rr,(FW d, FR s)) { int ds; - if (s==d) - make_tos(s); - else { - ds=stackpos(s); - emit_byte(0xd9); - emit_byte(0xc0+ds); /* duplicate source */ - } + usereg(s); + ds=stackpos(s); + emit_byte(0xd9); + emit_byte(0xc0+ds); /* duplicate source */ emit_byte(0xd9); emit_byte(0xe8); /* push '1' */ emit_byte(0xd9); emit_byte(0xc9); /* swap top two */ emit_byte(0xd9); emit_byte(0xf1); /* take 1*log2(x) */ - if (s!=d) - tos_make(d); /* store to destination */ + tos_make(d); /* store to destination */ } -LENDFUNC(NONE,NONE,2,raw_flog2_rr,(FW d, FR s)) LOWFUNC(NONE,NONE,2,raw_fneg_rr,(FW d, FR s)) @@ -4493,7 +2431,6 @@ LOWFUNC(NONE,NONE,2,raw_fneg_rr,(FW d, FR s)) emit_byte(0xe0); /* take fchs */ } } -LENDFUNC(NONE,NONE,2,raw_fneg_rr,(FW d, FR s)) LOWFUNC(NONE,NONE,2,raw_fadd_rr,(FRW d, FR s)) { @@ -4516,7 +2453,6 @@ LOWFUNC(NONE,NONE,2,raw_fadd_rr,(FRW d, FR s)) emit_byte(0xc0+ds); /* add source to dest*/ } } -LENDFUNC(NONE,NONE,2,raw_fadd_rr,(FRW d, FR s)) LOWFUNC(NONE,NONE,2,raw_fsub_rr,(FRW d, FR s)) { @@ -4539,7 +2475,6 @@ LOWFUNC(NONE,NONE,2,raw_fsub_rr,(FRW d, FR s)) emit_byte(0xe0+ds); /* sub src from dest */ } } -LENDFUNC(NONE,NONE,2,raw_fsub_rr,(FRW d, FR s)) LOWFUNC(NONE,NONE,2,raw_fcmp_rr,(FR d, FR s)) { @@ -4554,7 +2489,6 @@ LOWFUNC(NONE,NONE,2,raw_fcmp_rr,(FR d, FR s)) emit_byte(0xdd); emit_byte(0xe0+ds); /* cmp dest with source*/ } -LENDFUNC(NONE,NONE,2,raw_fcmp_rr,(FR d, FR s)) LOWFUNC(NONE,NONE,2,raw_fmul_rr,(FRW d, FR s)) { @@ -4577,7 +2511,6 @@ LOWFUNC(NONE,NONE,2,raw_fmul_rr,(FRW d, FR s)) emit_byte(0xc8+ds); /* mul dest by source*/ } } -LENDFUNC(NONE,NONE,2,raw_fmul_rr,(FRW d, FR s)) LOWFUNC(NONE,NONE,2,raw_fdiv_rr,(FRW d, FR s)) { @@ -4600,7 +2533,6 @@ LOWFUNC(NONE,NONE,2,raw_fdiv_rr,(FRW d, FR s)) emit_byte(0xf0+ds); /* div dest by source*/ } } -LENDFUNC(NONE,NONE,2,raw_fdiv_rr,(FRW d, FR s)) LOWFUNC(NONE,NONE,2,raw_frem_rr,(FRW d, FR s)) { @@ -4618,7 +2550,6 @@ LOWFUNC(NONE,NONE,2,raw_frem_rr,(FRW d, FR s)) emit_byte(0xd9); emit_byte(0xf8); /* take rem from dest by source */ } -LENDFUNC(NONE,NONE,2,raw_frem_rr,(FRW d, FR s)) LOWFUNC(NONE,NONE,2,raw_frem1_rr,(FRW d, FR s)) { @@ -4636,7 +2567,6 @@ LOWFUNC(NONE,NONE,2,raw_frem1_rr,(FRW d, FR s)) emit_byte(0xd9); emit_byte(0xf5); /* take rem1 from dest by source */ } -LENDFUNC(NONE,NONE,2,raw_frem1_rr,(FRW d, FR s)) LOWFUNC(NONE,NONE,1,raw_ftst_r,(FR r)) @@ -4645,7 +2575,6 @@ LOWFUNC(NONE,NONE,1,raw_ftst_r,(FR r)) emit_byte(0xd9); /* ftst */ emit_byte(0xe4); } -LENDFUNC(NONE,NONE,1,raw_ftst_r,(FR r)) LOWFUNC(NONE,NONE,2,raw_fetoxM1_rr,(FW d, FR s)) { @@ -4672,20 +2601,13 @@ LOWFUNC(NONE,NONE,2,raw_fetoxM1_rr,(FW d, FR s)) emit_byte(0xe1); /* fsub x*log2(e) - int(x*log2(e)) */ emit_byte(0xd9); emit_byte(0xf0); /* f2xm1 (2^frac(x))-1 */ - emit_byte(0xd8); - emit_byte(0x05); - emit_long((uae_u32)&one); /* fadd (2^frac(x))-1 + 1 */ emit_byte(0xd9); - emit_byte(0xfd); /* fscale ((2^frac(x)))*2^int(x*log2(e)) */ + emit_byte(0xfd); /* fscale ((2^frac(x))-1)*2^int(x*log2(e)) */ emit_byte(0xdd); emit_byte(0xd9); /* fstp copy & pop */ - emit_byte(0xd8); - emit_byte(0x25); - emit_long((uae_u32)&one); /* fsub 1 */ if (s!=d) tos_make(d); /* store y=(e^x)-1 */ } -LENDFUNC(NONE,NONE,2,raw_fetoxM1_rr,(FW d, FR s)) LOWFUNC(NONE,NONE,2,raw_ftentox_rr,(FW d, FR s)) { @@ -4720,7 +2642,6 @@ LOWFUNC(NONE,NONE,2,raw_ftentox_rr,(FW d, FR s)) if (s!=d) tos_make(d); /* store y=10^x */ } -LENDFUNC(NONE,NONE,2,raw_ftentox_rr,(FW d, FR s)) LOWFUNC(NONE,NONE,3,raw_fsincos_rr,(FW d, FW c, FR s)) { @@ -4765,7 +2686,6 @@ LOWFUNC(NONE,NONE,3,raw_fsincos_rr,(FW d, FW c, FR s)) tos_make(d); /* store sin(x) to destination */ } } -LENDFUNC(NONE,NONE,3,raw_fsincos_rr,(FW d, FW c, FR s)) LOWFUNC(NONE,NONE,2,raw_fscale_rr,(FRW d, FR s)) { @@ -4786,7 +2706,6 @@ LOWFUNC(NONE,NONE,2,raw_fscale_rr,(FRW d, FR s)) tos_make(d); /* store y=y*(2^x) */ } } -LENDFUNC(NONE,NONE,2,raw_fscale_rr,(FRW d, FR s)) LOWFUNC(NONE,NONE,2,raw_ftan_rr,(FW d, FR s)) { @@ -4810,7 +2729,6 @@ LOWFUNC(NONE,NONE,2,raw_ftan_rr,(FW d, FR s)) emit_byte(0xd8); /* fstp pop 1.0 */ } } -LENDFUNC(NONE,NONE,2,raw_ftan_rr,(FW d, FR s)) #ifdef CPU_x86_64 #define REX64() emit_byte(0x48) @@ -4837,7 +2755,6 @@ LOWFUNC(NONE,NONE,1,raw_fcuts_r,(FRW r)) emit_byte(0xc4); emit_byte(0x04); /* add +4 to esp */ } -LENDFUNC(NONE,NONE,1,raw_fcuts_r,(FRW r)) LOWFUNC(NONE,NONE,1,raw_fcut_r,(FRW r)) { @@ -4858,7 +2775,6 @@ LOWFUNC(NONE,NONE,1,raw_fcut_r,(FRW r)) emit_byte(0xc4); emit_byte(0x08); /* add +8 to esp */ } -LENDFUNC(NONE,NONE,1,raw_fcut_r,(FRW r)) LOWFUNC(NONE,NONE,2,raw_fgetexp_rr,(FW d, FR s)) { @@ -4882,7 +2798,6 @@ LOWFUNC(NONE,NONE,2,raw_fgetexp_rr,(FW d, FR s)) emit_byte(0xd8); /* fstp just pop man */ } } -LENDFUNC(NONE,NONE,2,raw_fgetexp_rr,(FW d, FR s)) LOWFUNC(NONE,NONE,2,raw_fgetman_rr,(FW d, FR s)) { @@ -4906,7 +2821,6 @@ LOWFUNC(NONE,NONE,2,raw_fgetman_rr,(FW d, FR s)) emit_byte(0xd9); /* fstp copy man up & pop */ } } -LENDFUNC(NONE,NONE,2,raw_fgetman_rr,(FW d, FR s)) LOWFUNC(NONE,NONE,2,raw_flogN_rr,(FW d, FR s)) { @@ -4928,7 +2842,6 @@ LOWFUNC(NONE,NONE,2,raw_flogN_rr,(FW d, FR s)) if (s!=d) tos_make(d); /* store y=logN(x) */ } -LENDFUNC(NONE,NONE,2,raw_flogN_rr,(FW d, FR s)) LOWFUNC(NONE,NONE,2,raw_flogNP1_rr,(FW d, FR s)) { @@ -4950,7 +2863,6 @@ LOWFUNC(NONE,NONE,2,raw_flogNP1_rr,(FW d, FR s)) if (s!=d) tos_make(d); /* store y=logN(x+1) */ } -LENDFUNC(NONE,NONE,2,raw_flogNP1_rr,(FW d, FR s)) LOWFUNC(NONE,NONE,2,raw_flog10_rr,(FW d, FR s)) { @@ -4972,7 +2884,6 @@ LOWFUNC(NONE,NONE,2,raw_flog10_rr,(FW d, FR s)) if (s!=d) tos_make(d); /* store y=log10(x) */ } -LENDFUNC(NONE,NONE,2,raw_flog10_rr,(FW d, FR s)) LOWFUNC(NONE,NONE,2,raw_fasin_rr,(FW d, FR s)) { @@ -4997,9 +2908,8 @@ LOWFUNC(NONE,NONE,2,raw_fasin_rr,(FW d, FR s)) emit_byte(0xf3); /* fpatan atan(x/sqrt(1-(x^2))) & pop */ tos_make(d); /* store y=asin(x) */ } -LENDFUNC(NONE,NONE,2,raw_fasin_rr,(FW d, FR s)) -static uae_u32 pihalf[] = {0x2168c235, 0xc90fdaa2, 0x3fff}; +static uae_u32 const pihalf[] = {0x2168c234, 0xc90fdaa2, 0x3fff}; // LSB=0 to get acos(1)=0 LOWFUNC(NONE,NONE,2,raw_facos_rr,(FW d, FR s)) { @@ -5027,7 +2937,6 @@ LOWFUNC(NONE,NONE,2,raw_facos_rr,(FW d, FR s)) emit_byte(0xe1); /* fsubrp pi/2 - asin(x) & pop */ tos_make(d); /* store y=acos(x) */ } -LENDFUNC(NONE,NONE,2,raw_facos_rr,(FW d, FR s)) LOWFUNC(NONE,NONE,2,raw_fatan_rr,(FW d, FR s)) { @@ -5047,7 +2956,6 @@ LOWFUNC(NONE,NONE,2,raw_fatan_rr,(FW d, FR s)) if (s!=d) tos_make(d); /* store y=atan(x) */ } -LENDFUNC(NONE,NONE,2,raw_fatan_rr,(FW d, FR s)) LOWFUNC(NONE,NONE,2,raw_fatanh_rr,(FW d, FR s)) { @@ -5065,7 +2973,7 @@ LOWFUNC(NONE,NONE,2,raw_fatanh_rr,(FW d, FR s)) emit_byte(0xde); emit_byte(0xf9); /* fdivp (1+x)/(1-x) */ emit_byte(0xd9); - emit_byte(0xed); /* fldln2 logN(2) */ + emit_byte(0xed); /* fldl2e logN(2) */ emit_byte(0xd9); emit_byte(0xc9); /* fxch swap logN(2) with (1+x)/(1-x) */ emit_byte(0xd9); @@ -5082,7 +2990,6 @@ LOWFUNC(NONE,NONE,2,raw_fatanh_rr,(FW d, FR s)) emit_byte(0xd9); /* fstp copy & pop */ tos_make(d); /* store y=atanh(x) */ } -LENDFUNC(NONE,NONE,2,raw_fatanh_rr,(FW d, FR s)) LOWFUNC(NONE,NONE,2,raw_fsinh_rr,(FW d, FR s)) { @@ -5175,7 +3082,6 @@ LOWFUNC(NONE,NONE,2,raw_fsinh_rr,(FW d, FR s)) if (s!=d) tos_make(d); /* store y=sinh(x) */ } -LENDFUNC(NONE,NONE,2,raw_fsinh_rr,(FW d, FR s)) LOWFUNC(NONE,NONE,2,raw_fcosh_rr,(FW d, FR s)) { @@ -5264,7 +3170,6 @@ LOWFUNC(NONE,NONE,2,raw_fcosh_rr,(FW d, FR s)) if (s!=d) tos_make(d); /* store y=cosh(x) */ } -LENDFUNC(NONE,NONE,2,raw_fcosh_rr,(FW d, FR s)) LOWFUNC(NONE,NONE,2,raw_ftanh_rr,(FW d, FR s)) { @@ -5353,7 +3258,6 @@ LOWFUNC(NONE,NONE,2,raw_ftanh_rr,(FW d, FR s)) if (s!=d) tos_make(d); /* store y=tanh(x) */ } -LENDFUNC(NONE,NONE,2,raw_ftanh_rr,(FW d, FR s)) /* %eax register is clobbered if target processor doesn't support fucomi */ #define FFLAG_NREG_CLOBBER_CONDITION !have_cmov diff --git a/jit/codegen_x86.h b/jit/codegen_x86.h index b37b48f8..0eaef50a 100644 --- a/jit/codegen_x86.h +++ b/jit/codegen_x86.h @@ -402,22 +402,54 @@ typedef unsigned int _ul; /* --- Memory subformats - urgh! ------------------------------------------- */ /* _r_D() is RIP addressing mode if X86_TARGET_64BIT, use _r_DSIB() instead */ -#define _r_D( R, D ) (_Mrm(_b00,_rN(R),_b101 ) ,_L((long)(D))) -#define _r_DSIB(R, D ) (_Mrm(_b00,_rN(R),_b100 ),_SIB(_SCL(1),_b100 ,_b101 ),_L((long)(D))) +#define _r_D( R, D ) (_Mrm(_b00,_rN(R),_b101 ) ,_L((uae_u32)(D))) +#define _r_DSIB(R, D ) (_Mrm(_b00,_rN(R),_b100 ),_SIB(_SCL(1),_b100 ,_b101 ),_L((uae_u32)(D))) #define _r_0B( R, B ) (_Mrm(_b00,_rN(R),_rA(B)) ) #define _r_0BIS(R, B,I,S) (_Mrm(_b00,_rN(R),_b100 ),_SIB(_SCL(S),_rA(I),_rA(B)) ) -#define _r_1B( R, D,B ) (_Mrm(_b01,_rN(R),_rA(B)) ,_B((long)(D))) -#define _r_1BIS(R, D,B,I,S) (_Mrm(_b01,_rN(R),_b100 ),_SIB(_SCL(S),_rA(I),_rA(B)),_B((long)(D))) -#define _r_4B( R, D,B ) (_Mrm(_b10,_rN(R),_rA(B)) ,_L((long)(D))) -#define _r_4IS( R, D,I,S) (_Mrm(_b00,_rN(R),_b100 ),_SIB(_SCL(S),_rA(I),_b101 ),_L((long)(D))) -#define _r_4BIS(R, D,B,I,S) (_Mrm(_b10,_rN(R),_b100 ),_SIB(_SCL(S),_rA(I),_rA(B)),_L((long)(D))) +#define _r_1B( R, D,B ) (_Mrm(_b01,_rN(R),_rA(B)) ,_B((uae_u32)(D))) +#define _r_1BIS(R, D,B,I,S) (_Mrm(_b01,_rN(R),_b100 ),_SIB(_SCL(S),_rA(I),_rA(B)),_B((uae_u32)(D))) +#define _r_4B( R, D,B ) (_Mrm(_b10,_rN(R),_rA(B)) ,_L((uae_u32)(D))) +#define _r_4IS( R, D,I,S) (_Mrm(_b00,_rN(R),_b100 ),_SIB(_SCL(S),_rA(I),_b101 ),_L((uae_u32)(D))) +#define _r_4BIS(R, D,B,I,S) (_Mrm(_b10,_rN(R),_b100 ),_SIB(_SCL(S),_rA(I),_rA(B)),_L((uae_u32)(D))) #define _r_DB( R, D,B ) ((_s0P(D) && (!_rbp13P(B)) ? _r_0B (R, B ) : (_s8P(D) ? _r_1B( R,D,B ) : _r_4B( R,D,B )))) #define _r_DBIS(R, D,B,I,S) ((_s0P(D) && (!_rbp13P(B)) ? _r_0BIS(R, B,I,S) : (_s8P(D) ? _r_1BIS(R,D,B,I,S) : _r_4BIS(R,D,B,I,S)))) /* Use RIP-addressing in 64-bit mode, if possible */ -#define _x86_RIP_addressing_possible(D,O) (X86_RIP_RELATIVE_ADDR && \ - ((uintptr)x86_get_target() + 4 + (O) - (D) <= 0xffffffff)) +#define _x86_RIP_addressing_possible(D,O) (X86_RIP_RELATIVE_ADDR && x86_RIP_addressing_possible(D, O)) + +static inline int x86_RIP_addressing_possible(uintptr addr, uintptr offset) +{ +#if X86_TARGET_64BIT + /* + * address of the next instruction. + * The opcode has already been emmitted, + * so this is the size of an 32bit displacement + + * the size of any immediate value that is part of the instruction (offset), + */ + uintptr dst = (uintptr)get_target() + 4 + offset; + intptr disp = dst - addr; + int ok = disp >= -0x80000000LL && disp <= 0x7fffffffLL; + /* fprintf(stderr, "x86_RIP_addressing_possible: %llx - %llx %16llx = %d\n", (unsigned long long)dst, (unsigned long long)addr, (long long)disp, ok); */ + return ok; +#else + UNUSED(addr); + UNUSED(offset); + return 0; +#endif +} + + +static inline int x86_DISP32_addressing_possible(uintptr addr) +{ +#if X86_TARGET_64BIT + return addr <= 0xFFFFFFFFULL; +#else + UNUSED(addr); + return 1; +#endif +} + #define _r_X( R, D,B,I,S,O) (_r0P(I) ? (_r0P(B) ? (!X86_TARGET_64BIT ? _r_D(R,D) : \ (_x86_RIP_addressing_possible(D, O) ? \ @@ -1251,14 +1283,14 @@ enum { /* _format Opcd ,Mod ,r ,m ,mem=dsp+sib ,imm... */ -// FIXME: no prefix is available to encode a 32-bit operand size in 64-bit mode +// FIXME: no prefix is availble to encode a 32-bit operand size in 64-bit mode #define CALLm(M) _O_D32 (0xe8 ,(int)(M) ) #define _CALLLsr(R) (_REXLrr(0, R), _O_Mrm (0xff ,_b11,_b010,_r4(R) )) #define _CALLQsr(R) (_REXQrr(0, R), _O_Mrm (0xff ,_b11,_b010,_r8(R) )) #define CALLsr(R) ( X86_TARGET_64BIT ? _CALLQsr(R) : _CALLLsr(R)) #define CALLsm(D,B,I,S) (_REXLrm(0, B, I), _O_r_X (0xff ,_b010 ,(int)(D),B,I,S )) -// FIXME: no prefix is available to encode a 32-bit operand size in 64-bit mode +// FIXME: no prefix is availble to encode a 32-bit operand size in 64-bit mode #define JMPSm(M) _O_D8 (0xeb ,(int)(M) ) #define JMPm(M) _O_D32 (0xe9 ,(int)(M) ) #define _JMPLsr(R) (_REXLrr(0, R), _O_Mrm (0xff ,_b11,_b100,_r4(R) )) diff --git a/jit/compemu.h b/jit/compemu.h index 5dd6d55a..70f76dcd 100644 --- a/jit/compemu.h +++ b/jit/compemu.h @@ -38,6 +38,7 @@ #ifdef UAE #ifdef CPU_64_BIT typedef uae_u64 uintptr; +typedef uae_s64 intptr; #else typedef uae_u32 uintptr; #endif @@ -130,19 +131,11 @@ union cacheline { for jump targets */ #define INDIVIDUAL_INST 0 -#ifdef WINUAE_ARANYM #define FLAG_X 0x0010 #define FLAG_N 0x0008 #define FLAG_Z 0x0004 #define FLAG_V 0x0002 #define FLAG_C 0x0001 -#else -#define FLAG_C 0x0010 -#define FLAG_V 0x0008 -#define FLAG_Z 0x0004 -#define FLAG_N 0x0002 -#define FLAG_X 0x0001 -#endif #define FLAG_CZNV (FLAG_C | FLAG_Z | FLAG_N | FLAG_V) #define FLAG_ALL (FLAG_C | FLAG_Z | FLAG_N | FLAG_V | FLAG_X) #define FLAG_ZNV (FLAG_Z | FLAG_N | FLAG_V) @@ -163,33 +156,78 @@ union cacheline { /* Functions exposed to newcpu, or to what was moved from newcpu.c to * compemu_support.c */ -#ifdef WINUAE_ARANYM extern void compiler_init(void); extern void compiler_exit(void); extern bool compiler_use_jit(void); -#endif -extern void init_comp(void); extern void flush(int save_regs); -extern void small_flush(int save_regs); +void flush_reg(int reg); extern void set_target(uae_u8* t); extern uae_u8* get_target(void); -extern void freescratch(void); +#ifdef UAE extern void build_comp(void); +#endif extern void set_cache_state(int enabled); extern int get_cache_state(void); extern uae_u32 get_jitted_size(void); #ifdef JIT -#ifdef WINUAE_ARANYM -extern void (*flush_icache)(int n); -#else -extern void flush_icache(int n); -extern void flush_icache_hard(int n); -#endif +extern void (*flush_icache)(int); #endif extern void alloc_cache(void); extern int check_for_cache_miss(void); /* JIT FPU compilation */ +struct jit_disable_opcodes { + bool fbcc; + bool fdbcc; + bool fscc; + bool ftrapcc; + bool fsave; + bool frestore; + bool fmove; + bool fmovem; + bool fmovec; /* for move control register */ + bool fmovecr; /* for move from constant rom */ + bool fint; + bool fsinh; + bool fintrz; + bool fsqrt; + bool flognp1; + bool fetoxm1; + bool ftanh; + bool fatan; + bool fasin; + bool fatanh; + bool fsin; + bool ftan; + bool fetox; + bool ftwotox; + bool ftentox; + bool flogn; + bool flog10; + bool flog2; + bool fabs; + bool fcosh; + bool fneg; + bool facos; + bool fcos; + bool fgetexp; + bool fgetman; + bool fdiv; + bool fmod; + bool fadd; + bool fmul; + bool fsgldiv; + bool frem; + bool fscale; + bool fsglmul; + bool fsub; + bool fsincos; + bool fcmp; + bool ftst; +}; +extern struct jit_disable_opcodes jit_disable; + + extern void comp_fpp_opp (uae_u32 opcode, uae_u16 extra); extern void comp_fbcc_opp (uae_u32 opcode); extern void comp_fscc_opp (uae_u32 opcode, uae_u16 extra); @@ -233,6 +271,7 @@ typedef struct { uae_u8 needflush; } freg_status; +#define SP_REG 15 #define PC_P 16 #define FLAGX 17 #define FLAGTMP 18 @@ -324,18 +363,20 @@ extern int touchcnt; #define RW4 uae_u32 #define MEMR uae_u32 #define MEMW uae_u32 -#define MEMRW uae_u32 +#define MEMRW uae_u32 +#define MEMPTR uintptr +#define MEMPTRR MEMPTR +#define MEMPTRW MEMPTR +#define MEMPTRRW MEMPTR #define FW uae_u32 #define FR uae_u32 #define FRW uae_u32 #define MIDFUNC(nargs,func,args) void func args -#define MENDFUNC(nargs,func,args) #define COMPCALL(func) func #define LOWFUNC(flags,mem,nargs,func,args) static inline void func args -#define LENDFUNC(flags,mem,nargs,func,args) /* What we expose to the outside */ #define DECLARE_MIDFUNC(func) extern void func @@ -379,6 +420,11 @@ extern void sync_m68k_pc(void); extern uae_u32 get_const(int r); extern int is_const(int r); extern void register_branch(uae_u32 not_taken, uae_u32 taken, uae_u8 cond); +void compemu_make_sr(int sr, int tmp); +void compemu_enter_super(int sr); +void compemu_exc_make_frame(int format, int sr, int currpc, int nr, int tmp); +void compemu_bkpt(void); +extern bool disasm_this_inst; #define comp_get_ibyte(o) do_get_mem_byte((uae_u8 *)(comp_pc_p + (o) + 1)) #define comp_get_iword(o) do_get_mem_word((uae_u16 *)(comp_pc_p + (o))) @@ -460,19 +506,12 @@ void do_nothing(void); #else -static inline void flush_icache(int) { } -static inline void build_comp() { } +static inline void flush_icache(void) { } #endif /* !USE_JIT */ #ifdef UAE -typedef struct { - uae_u8 type; - uae_u8 reg; - uae_u32 next; -} regacc; - #define JIT_EXCEPTION_HANDLER // #define JIT_ALWAYS_DISTRUST @@ -488,20 +527,16 @@ extern void compile_block(cpu_history* pc_hist, int blocklen, int totcyles); /* Flags for Bernie during development/debugging. Should go away eventually */ #define DISTRUST_CONSISTENT_MEM 0 -typedef struct { - uae_u8 use_flags; - uae_u8 set_flags; - uae_u8 is_jump; - uae_u8 is_addx; - uae_u8 is_const_jump; -} op_properties; - +struct op_properties { + uae_u8 use_flags; + uae_u8 set_flags; + uae_u8 is_addx; + uae_u8 cflow; +}; extern op_properties prop[65536]; - -STATIC_INLINE int end_block(uae_u16 opcode) +static inline int end_block(uae_u32 opcode) { - return prop[opcode].is_jump || - (prop[opcode].is_const_jump && !currprefs.comp_constjump); + return (prop[opcode].cflow & fl_end_block); } #ifdef _WIN32 diff --git a/jit/compemu_fpp.cpp b/jit/compemu_fpp.cpp index 3a14920e..ac39bc71 100644 --- a/jit/compemu_fpp.cpp +++ b/jit/compemu_fpp.cpp @@ -1,1471 +1,2096 @@ /* - * UAE - The Un*x Amiga Emulator - * - * MC68881 emulation - * - * Copyright 1996 Herman ten Brugge - * Adapted for JIT compilation (c) Bernd Meyer, 2000 - * Modified 2005 Peter Keunecke - */ - -#include "sysconfig.h" + * compiler/compemu_fpp.cpp - Dynamic translation of FPU instructions + * + * Copyright (c) 2001-2004 Milan Jurik of ARAnyM dev team (see AUTHORS) + * + * Inspired by Christian Bauer's Basilisk II + * + * This file is part of the ARAnyM project which builds a new and powerful + * TOS/FreeMiNT compatible virtual machine running on almost any hardware. + * + * JIT compiler m68k -> IA-32 and AMD64 + * + * Original 68040 JIT compiler for UAE, copyright 2000-2002 Bernd Meyer + * Adaptation for Basilisk II and improvements, copyright 2000-2004 Gwenole Beauchesne + * Portions related to CPU detection come from linux/arch/i386/kernel/setup.c + * + * ARAnyM is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * ARAnyM is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ARAnyM; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +/* + * UAE - The Un*x Amiga Emulator + * + * MC68881 emulation + * + * Copyright 1996 Herman ten Brugge + * Adapted for JIT compilation (c) Bernd Meyer, 2000 + */ + #include "sysdeps.h" -#include "options.h" -#include "memory.h" -#include "custom.h" +#include +#include +#include + +#include "memory-uae.h" +#include "readcpu.h" #include "newcpu.h" -#include "ersatz.h" -#include "md-fpp.h" #include "compemu.h" +//#include "fpu/fpu.h" +//#include "fpu/flags.h" +//#include "fpu/exceptions.h" +//#include "fpu/rounding.h" -#if defined(JIT) -uae_u32 temp_fp[] = { 0, 0, 0 }; /* To convert between FP and */ +#define DEBUG 0 +#include "debug.h" -/* 128 words, indexed through the low byte of the 68k fpu control word */ -static const uae_u16 x86_fpucw[] = { - 0x137f, 0x137f, 0x137f, 0x137f, 0x137f, 0x137f, 0x137f, 0x137f, /* E-RN */ - 0x1f7f, 0x1f7f, 0x1f7f, 0x1f7f, 0x1f7f, 0x1f7f, 0x1f7f, 0x1f7f, /* E-RZ */ - 0x177f, 0x177f, 0x177f, 0x177f, 0x177f, 0x177f, 0x177f, 0x177f, /* E-RD */ - 0x1b7f, 0x1b7f, 0x1b7f, 0x1b7f, 0x1b7f, 0x1b7f, 0x1b7f, 0x1b7f, /* E-RU */ - - 0x107f, 0x107f, 0x107f, 0x107f, 0x107f, 0x107f, 0x107f, 0x107f, /* S-RN */ - 0x1c7f, 0x1c7f, 0x1c7f, 0x1c7f, 0x1c7f, 0x1c7f, 0x1c7f, 0x1c7f, /* S-RZ */ - 0x147f, 0x147f, 0x147f, 0x147f, 0x147f, 0x147f, 0x147f, 0x147f, /* S-RD */ - 0x187f, 0x187f, 0x187f, 0x187f, 0x187f, 0x187f, 0x187f, 0x187f, /* S-RU */ - - 0x127f, 0x127f, 0x127f, 0x127f, 0x127f, 0x127f, 0x127f, 0x127f, /* D-RN */ - 0x1e7f, 0x1e7f, 0x1e7f, 0x1e7f, 0x1e7f, 0x1e7f, 0x1e7f, 0x1e7f, /* D-RZ */ - 0x167f, 0x167f, 0x167f, 0x167f, 0x167f, 0x167f, 0x167f, 0x167f, /* D-RD */ - 0x1a7f, 0x1a7f, 0x1a7f, 0x1a7f, 0x1a7f, 0x1a7f, 0x1a7f, 0x1a7f, /* D-RU */ - - 0x137f, 0x137f, 0x137f, 0x137f, 0x137f, 0x137f, 0x137f, 0x137f, /* ?-RN */ - 0x1f7f, 0x1f7f, 0x1f7f, 0x1f7f, 0x1f7f, 0x1f7f, 0x1f7f, 0x1f7f, /* ?-RZ */ - 0x177f, 0x177f, 0x177f, 0x177f, 0x177f, 0x177f, 0x177f, 0x177f, /* ?-RD */ - 0x1b7f, 0x1b7f, 0x1b7f, 0x1b7f, 0x1b7f, 0x1b7f, 0x1b7f, 0x1b7f /* ?-RU */ -}; -static const int sz1[8] = { 4, 4, 12, 12, 2, 8, 1, 0 }; -static const int sz2[8] = { 4, 4, 12, 12, 2, 8, 2, 0 }; - -static struct { - double b[2]; - double w[2]; - double l[2]; -} clamp_bounds = { - { -128.0, 127.0 }, - { -32768.0, 32767.0 }, - { -2147483648.0, 2147483647.0 } -}; +struct jit_disable_opcodes jit_disable; + +#if defined(USE_LONG_DOUBLE) || defined(USE_QUAD_DOUBLE) +#define LD(x) x ## L +#else +#define LD(x) x +#endif + +// gb-- WARNING: get_fpcr() and set_fpcr() support is experimental +#define HANDLE_FPCR 0 + +// - IEEE-based fpu core must be used +#if defined(FPU_IEEE) +# define CAN_HANDLE_FPCR +#endif + +// - Generic rounding mode and precision modes are supported if set together +#if defined(FPU_USE_GENERIC_ROUNDING_MODE) && defined(FPU_USE_GENERIC_ROUNDING_PRECISION) +# define CAN_HANDLE_FPCR +#endif + +// - X86 rounding mode and precision modes are *not* supported but might work (?!) +#if defined(FPU_USE_X86_ROUNDING_MODE) && defined(FPU_USE_X86_ROUNDING_PRECISION) +# define CAN_HANDLE_FPCR +#endif -/* return the required floating point precision or -1 for failure, 0=E, 1=S, 2=D */ -STATIC_INLINE int comp_fp_get (uae_u32 opcode, uae_u16 extra, int treg) +#if HANDLE_FPCR && !defined(CAN_HANDLE_FPCR) +# warning "Can't handle FPCR, will FAIL(1) at runtime" +# undef HANDLE_FPCR +# define HANDLE_FPCR 0 +#endif + +//#define STATIC_INLINE static inline +#define MAKE_FPSR(r) do { fmov_rr(FP_RESULT,r); } while (0) + +#define delay nop() ;nop() +#define delay2 nop() ;nop() + +#define UNKNOWN_EXTRA 0xFFFFFFFF +#if 0 +static void fpuop_illg(uae_u32 opcode, uae_u32 /* extra */) { - int reg = opcode & 7; - int mode = (opcode >> 3) & 7; - int size = (extra >> 10) & 7; +/* + if (extra == UNKNOWN_EXTRA) + printf("FPU opcode %x, extra UNKNOWN_EXTRA\n",opcode & 0xFFFF); + else + printf("FPU opcode %x, extra %x\n",opcode & 0xFFFF,extra & 0xFFFF); +*/ + op_illg(opcode); +} +#endif - if (size == 3 || size == 7) /* 3 = packed decimal, 7 is not defined */ - return -1; - switch (mode) { - case 0: /* Dn */ - switch (size) { - case 0: /* Long */ - mov_l_mr (uae_p32(temp_fp), reg); - fmovi_rm (treg, uae_p32(temp_fp)); - return 2; - case 1: /* Single */ - mov_l_mr (uae_p32(temp_fp), reg); - fmovs_rm (treg, uae_p32(temp_fp)); - return 1; - case 4: /* Word */ - sign_extend_16_rr (S1, reg); - mov_l_mr (uae_p32(temp_fp), S1); - fmovi_rm (treg, uae_p32(temp_fp)); - return 1; - case 6: /* Byte */ - sign_extend_8_rr (S1, reg); - mov_l_mr (uae_p32(temp_fp), S1); - fmovi_rm (treg, uae_p32(temp_fp)); - return 1; - default: +uae_s32 temp_fp[4]; /* To convert between FP/integer */ + +/* return register number, or -1 for failure */ +STATIC_INLINE int get_fp_value(uae_u32 opcode, uae_u16 extra) +{ + int size; + int mode; + int reg; + uae_u32 ad = 0; + static int const sz1[8] = { 4, 4, 12, 12, 2, 8, 1, 0 }; + static int const sz2[8] = { 4, 4, 12, 12, 2, 8, 2, 0 }; + + if ((extra & 0x4000) == 0) + { + return ((extra >> 10) & 7); + } + + mode = (opcode >> 3) & 7; + reg = opcode & 7; + size = (extra >> 10) & 7; + switch (mode) + { + case 0: /* Dn */ + switch (size) + { + case 6: /* byte */ + sign_extend_8_rr(S1, reg); + mov_l_mr((uintptr) temp_fp, S1); + delay2; + fmovi_rm(FS1, (uintptr) temp_fp); + return FS1; + case 4: /* word */ + sign_extend_16_rr(S1, reg); + mov_l_mr((uintptr) temp_fp, S1); + delay2; + fmovi_rm(FS1, (uintptr) temp_fp); + return FS1; + case 0: /* long */ + mov_l_mr((uintptr) temp_fp, reg); + delay2; + fmovi_rm(FS1, (uintptr) temp_fp); + return FS1; + case 1: /* single precision */ + mov_l_mr((uintptr) temp_fp, reg); + delay2; + fmovs_rm(FS1, (uintptr) temp_fp); + return FS1; + default: return -1; } - case 1: /* An, invalid mode */ + return -1; /* Should be unreachable */ + case 1: /* An */ + return -1; /* Genuine invalid instruction */ + default: + break; + } + + /* OK, we *will* have to load something from an address. Let's make + sure we know how to handle that, or quit early --- i.e. *before* + we do any postincrement/predecrement that we may regret */ + switch (size) + { + case 0: /* long */ + case 1: /* single precision */ + case 2: /* extended precision */ + case 4: /* word */ + case 5: /* double precision */ + case 6: /* byte */ + break; + case 3: /* packed decimal static */ + default: return -1; - case 2: /* (An) */ - mov_l_rr (S1, reg + 8); + } + + switch (mode) + { + case 2: /* (An) */ + ad = S1; /* We will change it, anyway ;-) */ + mov_l_rr(ad, reg + 8); break; - case 3: /* (An)+ */ - mov_l_rr (S1, reg + 8); - lea_l_brr (reg + 8, reg + 8, (reg == 7 ? sz2[size] : sz1[size])); + case 3: /* (An)+ */ + ad = S1; + mov_l_rr(ad, reg + 8); + lea_l_brr(reg + 8, reg + 8, (reg == 7 ? sz2[size] : sz1[size])); break; - case 4: /* -(An) */ - lea_l_brr (reg + 8, reg + 8, -(reg == 7 ? sz2[size] : sz1[size])); - mov_l_rr (S1, reg + 8); + case 4: /* -(An) */ + ad = S1; + lea_l_brr(reg + 8, reg + 8, -(reg == 7 ? sz2[size] : sz1[size])); + mov_l_rr(ad, reg + 8); break; - case 5: /* (d16,An) */ + case 5: /* d16(An) */ { - uae_u32 off = (uae_s32) (uae_s16) comp_get_iword ((m68k_pc_offset += 2) - 2); - mov_l_rr (S1, reg + 8); - lea_l_brr (S1, S1, off); - break; + uae_u32 off = (uae_s32) (uae_s16) comp_get_iword((m68k_pc_offset += 2) - 2); + + ad = S1; + mov_l_rr(ad, reg + 8); + lea_l_brr(ad, ad, off); } - case 6: /* (d8,An,Xn) or (bd,An,Xn) or ([bd,An,Xn],od) or ([bd,An],Xn,od) */ + break; + case 6: /* d8(An,Xn) */ { - uae_u32 dp = comp_get_iword ((m68k_pc_offset += 2) - 2); - calc_disp_ea_020 (reg + 8, dp, S1, S2); - break; + uae_u32 dp = comp_get_iword((m68k_pc_offset += 2) - 2); + + ad = S1; + calc_disp_ea_020(reg + 8, dp, ad, S2); } - case 7: - switch (reg) { - case 0: /* (xxx).W */ + break; + case 7: + switch (reg) + { + case 0: /* abs.w */ { - uae_u32 off = (uae_s32) (uae_s16) comp_get_iword ((m68k_pc_offset += 2) - 2); - mov_l_ri (S1, off); - break; + uae_u32 off = (uae_s32) (uae_s16) comp_get_iword((m68k_pc_offset += 2) - 2); + + ad = S1; + mov_l_ri(ad, off); } - case 1: /* (xxx).L */ + break; + case 1: /* abs.l */ { - uae_u32 off = comp_get_ilong ((m68k_pc_offset += 4) - 4); - mov_l_ri (S1, off); - break; + uae_u32 off = comp_get_ilong((m68k_pc_offset += 4) - 4); + + ad = S1; + mov_l_ri(ad, off); } - case 2: /* (d16,PC) */ + break; + case 2: /* d16(pc) */ { - uae_u32 address = start_pc + ((uae_char*) comp_pc_p - (uae_char*) start_pc_p) + m68k_pc_offset; - uae_s32 PC16off = (uae_s32) (uae_s16) comp_get_iword ((m68k_pc_offset += 2) - 2); - mov_l_ri (S1, address + PC16off); - break; + uae_u32 address = start_pc + ((char *) comp_pc_p - (char *) start_pc_p) + m68k_pc_offset; + uae_s32 PC16off = (uae_s32) (uae_s16) comp_get_iword((m68k_pc_offset += 2) - 2); + + ad = S1; + mov_l_ri(ad, address + PC16off); } - case 3: /* (d8,PC,Xn) or (bd,PC,Xn) or ([bd,PC,Xn],od) or ([bd,PC],Xn,od) */ + break; + case 3: /* d8(pc,Xn) */ + return -1; + case 4: /* #imm */ { - uae_u32 address = start_pc + ((uae_char*)comp_pc_p - (uae_char*)start_pc_p) + m68k_pc_offset; - uae_u32 dp = comp_get_iword((m68k_pc_offset += 2) - 2); - mov_l_ri(S3, address); - calc_disp_ea_020(S3, dp, S1, S2); - break; - } - case 4: /* # < data >; Constants should be converted just once by the JIT */ - m68k_pc_offset += sz2[size]; - switch (size) { - case 0: - { - uae_s32 li = comp_get_ilong(m68k_pc_offset - 4); - float si = (float)li; - - if (li == (int)si) { - //write_log ("converted immediate LONG constant to SINGLE\n"); - mov_l_mi(uae_p32(temp_fp), *(uae_u32 *)&si); - fmovs_rm(treg, uae_p32(temp_fp)); - return 1; - } - //write_log ("immediate LONG constant\n"); - mov_l_mi(uae_p32(temp_fp), *(uae_u32 *)&li); - fmovi_rm(treg, uae_p32(temp_fp)); - return 2; - } - case 1: - //write_log (_T("immediate SINGLE constant\n")); - mov_l_mi(uae_p32(temp_fp), comp_get_ilong(m68k_pc_offset - 4)); - fmovs_rm(treg, uae_p32(temp_fp)); - return 1; - case 2: - //write_log (_T("immediate LONG DOUBLE constant\n")); - mov_l_mi(uae_p32(temp_fp), comp_get_ilong(m68k_pc_offset - 4)); - mov_l_mi((uae_p32(temp_fp)) + 4, comp_get_ilong(m68k_pc_offset - 8)); - mov_l_mi((uae_p32(temp_fp)) + 8, (uae_u32)comp_get_iword(m68k_pc_offset - 12)); - fmov_ext_rm(treg, uae_p32(temp_fp)); - return 0; - case 4: - { - float si = (float)(uae_s16)comp_get_iword(m68k_pc_offset-2); - - //write_log (_T("converted immediate WORD constant %f to SINGLE\n"), si); - mov_l_mi(uae_p32(temp_fp),*(uae_u32 *)&si); - fmovs_rm(treg,uae_p32(temp_fp)); - return 1; - } - case 5: - { - uae_u32 longarray[] = { comp_get_ilong(m68k_pc_offset - 4), - comp_get_ilong(m68k_pc_offset - 8) }; - float si = (float)*(double *)longarray; - - if (*(double *)longarray == (double)si) { - //write_log (_T("SPEED GAIN: converted a DOUBLE constant to SINGLE\n")); - mov_l_mi(uae_p32(temp_fp), *(uae_u32 *)&si); - fmovs_rm(treg, uae_p32(temp_fp)); - return 1; - } - //write_log (_T("immediate DOUBLE constant\n")); - mov_l_mi(uae_p32(temp_fp), longarray[0]); - mov_l_mi((uae_p32(temp_fp)) + 4, longarray[1]); - fmov_rm(treg, uae_p32(temp_fp)); - return 2; - } - case 6: - { - float si = (float)(uae_s8)comp_get_ibyte(m68k_pc_offset - 2); + uae_u32 address = start_pc + ((char *) comp_pc_p - (char *) start_pc_p) + m68k_pc_offset; - //write_log (_T("converted immediate BYTE constant to SINGLE\n")); - mov_l_mi(uae_p32(temp_fp), *(uae_u32 *)&si); - fmovs_rm(treg, uae_p32(temp_fp)); - return 1; - } - default: /* never reached */ - return -1; + ad = S1; + // Immediate addressing mode && Operation Length == Byte -> + // Use the low-order byte of the extension word. + if (size == 6) + address++; + mov_l_ri(ad, address); + m68k_pc_offset += sz2[size]; } - default: /* never reached */ + break; + default: return -1; } } - switch (size) { - case 0: /* Long */ - readlong (S1, S2, S3); - mov_l_mr (uae_p32(temp_fp), S2); - fmovi_rm (treg, uae_p32(temp_fp)); - return 2; - case 1: /* Single */ - readlong (S1, S2, S3); - mov_l_mr (uae_p32(temp_fp), S2); - fmovs_rm (treg, uae_p32(temp_fp)); - return 1; - case 2: /* Long Double */ - readword (S1, S2, S3); - mov_w_mr ((uae_p32(temp_fp)) + 8, S2); - add_l_ri (S1, 4); - readlong (S1, S2, S3); - mov_l_mr ((uae_p32(temp_fp)) + 4, S2); - add_l_ri (S1, 4); - readlong (S1, S2, S3); - mov_l_mr ((uae_p32(temp_fp)), S2); - fmov_ext_rm (treg, uae_p32(temp_fp)); - return 0; - case 4: /* Word */ - readword (S1, S2, S3); - sign_extend_16_rr (S2, S2); - mov_l_mr (uae_p32(temp_fp), S2); - fmovi_rm (treg, uae_p32(temp_fp)); - return 1; - case 5: /* Double */ - readlong (S1, S2, S3); - mov_l_mr ((uae_p32(temp_fp)) + 4, S2); - add_l_ri (S1, 4); - readlong (S1, S2, S3); - mov_l_mr ((uae_p32(temp_fp)), S2); - fmov_rm (treg, uae_p32(temp_fp)); - return 2; - case 6: /* Byte */ - readbyte (S1, S2, S3); - sign_extend_8_rr (S2, S2); - mov_l_mr (uae_p32(temp_fp), S2); - fmovi_rm (treg, uae_p32(temp_fp)); - return 1; - default: + switch (size) + { + case 0: /* long */ + readlong(ad, S2, S3); + mov_l_mr((uintptr) temp_fp, S2); + delay2; + fmovi_rm(FS1, (uintptr) temp_fp); + break; + case 1: /* single precision */ + readlong(ad, S2, S3); + mov_l_mr((uintptr) temp_fp, S2); + delay2; + fmovs_rm(FS1, (uintptr) temp_fp); + break; + case 2: /* extended precision */ + readword(ad, S2, S3); + mov_w_mr(((uintptr) temp_fp) + 8, S2); + add_l_ri(ad, 4); + readlong(ad, S2, S3); + // always set the explicit integer bit. + or_l_ri(S2, 0x80000000); + mov_l_mr((uintptr) (temp_fp) + 4, S2); + add_l_ri(ad, 4); + readlong(ad, S2, S3); + mov_l_mr((uintptr) (temp_fp), S2); + delay2; + fmov_ext_rm(FS1, (uintptr) (temp_fp)); + break; + case 3: /* packed decimal static */ + return -1; /* Some silly "packed" stuff */ + case 4: /* word */ + readword(ad, S2, S3); + sign_extend_16_rr(S2, S2); + mov_l_mr((uintptr) temp_fp, S2); + delay2; + fmovi_rm(FS1, (uintptr) temp_fp); + break; + case 5: /* double precision */ + readlong(ad, S2, S3); + mov_l_mr(((uintptr) temp_fp) + 4, S2); + add_l_ri(ad, 4); + readlong(ad, S2, S3); + mov_l_mr((uintptr) (temp_fp), S2); + delay2; + fmov_rm(FS1, (uintptr) (temp_fp)); + break; + case 6: /* byte */ + readbyte(ad, S2, S3); + sign_extend_8_rr(S2, S2); + mov_l_mr((uintptr) temp_fp, S2); + delay2; + fmovi_rm(FS1, (uintptr) temp_fp); + break; + default: return -1; } - return -1; + return FS1; } + /* return of -1 means failure, >=0 means OK */ -STATIC_INLINE int comp_fp_put (uae_u32 opcode, uae_u16 extra) +STATIC_INLINE int put_fp_value(int val, uae_u32 opcode, uae_u16 extra) { - int reg = opcode & 7; - int sreg = (extra >> 7) & 7; - int mode = (opcode >> 3) & 7; - int size = (extra >> 10) & 7; + int size; + int mode; + int reg; + uae_u32 ad; + static int const sz1[8] = { 4, 4, 12, 12, 2, 8, 1, 0 }; + static int const sz2[8] = { 4, 4, 12, 12, 2, 8, 2, 0 }; - if (size == 3 || size == 7) /* 3 = packed decimal, 7 is not defined */ - return -1; - switch (mode) { - case 0: /* Dn */ - switch (size) { - case 0: /* FMOVE.L FPx, Dn */ -#if USE_X86_FPUCW && 0 - if (!(regs.fpcr & 0xf0)) { /* if extended round to nearest */ - mov_l_ri(S1,0x10); /* use extended round to zero mode */ - fldcw_m_indexed(S1,(uae_u32)x86_fpucw); - fmovi_mrb(uae_p32(temp_fp),sreg, clamp_bounds.l); - mov_l_rm(reg,uae_p32(temp_fp)); - mov_l_rm(S1,(uae_u32)®s.fpcr); - and_l_ri(S1,0xf0); /* restore control word */ - fldcw_m_indexed(S1,(uae_u32)x86_fpucw); - return 0; - } -#endif - fmovi_mrb (uae_p32(temp_fp), sreg, clamp_bounds.l); - mov_l_rm (reg, uae_p32(temp_fp)); + if ((extra & 0x4000) == 0) + { + const int dest_reg = (extra >> 10) & 7; + + fmov_rr(dest_reg, val); + // gb-- status register is affected + MAKE_FPSR(dest_reg); + return 0; + } + + mode = (opcode >> 3) & 7; + reg = opcode & 7; + size = (extra >> 10) & 7; + ad = (uae_u32) -1; + switch (mode) + { + case 0: /* Dn */ + switch (size) + { + case 6: /* byte */ + fmovi_mr((uintptr) temp_fp, val); + delay; + mov_b_rm(reg, (uintptr) temp_fp); return 0; - case 1: /* FMOVE.S FPx, Dn */ - fmovs_mr (uae_p32(temp_fp), sreg); - mov_l_rm (reg, uae_p32(temp_fp)); + case 4: /* word */ + fmovi_mr((uintptr) temp_fp, val); + delay; + mov_w_rm(reg, (uintptr) temp_fp); return 0; - case 4: /* FMOVE.W FPx, Dn */ -#if USE_X86_FPUCW && 0 - if (!(regs.fpcr & 0xf0)) { /* if extended round to nearest */ - mov_l_ri(S1,0x10); /* use extended round to zero mode */ - fldcw_m_indexed(S1,(uae_u32)x86_fpucw); - fmovi_mrb(uae_p32(temp_fp),sreg, clamp_bounds.w); - mov_w_rm(reg,uae_p32(temp_fp)); - mov_l_rm(S1,(uae_u32)®s.fpcr); - and_l_ri(S1,0xf0); /* restore control word */ - fldcw_m_indexed(S1,(uae_u32)x86_fpucw); - return 0; - } -#endif - fmovi_mrb (uae_p32(temp_fp), sreg, clamp_bounds.w); - mov_w_rm (reg, uae_p32(temp_fp)); + case 0: /* long */ + fmovi_mr((uintptr) temp_fp, val); + delay; + mov_l_rm(reg, (uintptr) temp_fp); return 0; - case 6: /* FMOVE.B FPx, Dn */ -#if USE_X86_FPUCW && 0 - if (!(regs.fpcr & 0xf0)) { /* if extended round to nearest */ - mov_l_ri(S1,0x10); /* use extended round to zero mode */ - fldcw_m_indexed(S1,(uae_u32)x86_fpucw); - fmovi_mrb(uae_p32(temp_fp),sreg, clamp_bounds.b); - mov_b_rm(reg,uae_p32(temp_fp)); - mov_l_rm(S1,(uae_u32)®s.fpcr); - and_l_ri(S1,0xf0); /* restore control word */ - fldcw_m_indexed(S1,(uae_u32)x86_fpucw); - return 0; - } -#endif - fmovi_mrb (uae_p32(temp_fp), sreg, clamp_bounds.b); - mov_b_rm (reg, uae_p32(temp_fp)); + case 1: /* single precision */ + fmovs_mr((uintptr) temp_fp, val); + delay; + mov_l_rm(reg, (uintptr) temp_fp); return 0; - default: + default: return -1; } - case 1: /* An, invalid mode */ + case 1: /* An */ + return -1; /* genuine invalid instruction */ + default: + break; + } + + /* Let's make sure we get out *before* doing something silly if + we can't handle the size */ + switch (size) + { + case 0: /* long */ + case 1: /* single precision */ + case 2: /* extended precision */ + case 4: /* word */ + case 5: /* double precision */ + case 6: /* byte */ + break; + case 3: /* packed decimal static */ + default: return -1; - case 2: /* (An) */ - mov_l_rr (S1, reg + 8); + } + + switch (mode) + { + case 2: /* (An) */ + ad = S1; + mov_l_rr(ad, reg + 8); break; - case 3: /* (An)+ */ - mov_l_rr (S1, reg + 8); - lea_l_brr (reg + 8, reg + 8, (reg == 7 ? sz2[size] : sz1[size])); + case 3: /* (An)+ */ + ad = S1; + mov_l_rr(ad, reg + 8); + lea_l_brr(reg + 8, reg + 8, (reg == 7 ? sz2[size] : sz1[size])); break; - case 4: /* -(An) */ - lea_l_brr (reg + 8, reg + 8, -(reg == 7 ? sz2[size] : sz1[size])); - mov_l_rr (S1, reg + 8); + case 4: /* -(An) */ + ad = S1; + lea_l_brr(reg + 8, reg + 8, -(reg == 7 ? sz2[size] : sz1[size])); + mov_l_rr(ad, reg + 8); break; - case 5: /* (d16,An) */ + case 5: /* d16(An) */ { - uae_u32 off = (uae_s32) (uae_s16) comp_get_iword ((m68k_pc_offset += 2) - 2); - mov_l_rr (S1, reg + 8); - add_l_ri (S1, off); - break; + uae_u32 off = (uae_s32) (uae_s16) comp_get_iword((m68k_pc_offset += 2) - 2); + + ad = S1; + mov_l_rr(ad, reg + 8); + add_l_ri(ad, off); } - case 6: /* (d8,An,Xn) or (bd,An,Xn) or ([bd,An,Xn],od) or ([bd,An],Xn,od) */ + break; + case 6: /* d8(An,Xn) */ { - uae_u32 dp = comp_get_iword ((m68k_pc_offset += 2) - 2); - calc_disp_ea_020 (reg + 8, dp, S1, S2); - break; + uae_u32 dp = comp_get_iword((m68k_pc_offset += 2) - 2); + + ad = S1; + calc_disp_ea_020(reg + 8, dp, ad, S2); } - case 7: - switch (reg) { - case 0: /* (xxx).W */ + break; + case 7: + switch (reg) + { + case 0: /* abs.w */ { - uae_u32 off = (uae_s32) (uae_s16) comp_get_iword ((m68k_pc_offset += 2) - 2); - mov_l_ri (S1, off); - break; + uae_u32 off = (uae_s32) (uae_s16) comp_get_iword((m68k_pc_offset += 2) - 2); + + ad = S1; + mov_l_ri(ad, off); } - case 1: /* (xxx).L */ + break; + case 1: /* abs.l */ { - uae_u32 off = comp_get_ilong ((m68k_pc_offset += 4) - 4); - mov_l_ri (S1, off); - break; + uae_u32 off = comp_get_ilong((m68k_pc_offset += 4) - 4); + + ad = S1; + mov_l_ri(ad, off); + } + break; + case 2: /* d16(pc) */ + { + uae_u32 address = start_pc + ((char *) comp_pc_p - (char *) start_pc_p) + m68k_pc_offset; + uae_s32 PC16off = (uae_s32) (uae_s16) comp_get_iword((m68k_pc_offset += 2) - 2); + + ad = S1; + mov_l_ri(ad, address + PC16off); + } + break; + case 3: /* d8(pc,Xn) */ + return -1; + case 4: /* #imm */ + { + uae_u32 address = start_pc + ((char *) comp_pc_p - (char *) start_pc_p) + m68k_pc_offset; + + ad = S1; + mov_l_ri(ad, address); + m68k_pc_offset += sz2[size]; } - default: /* All other modes are not allowed for FPx to */ - write_log (_T ("JIT FMOVE FPx, Mode is not allowed %04x %04x\n"), opcode, extra); + break; + default: return -1; } } - switch (size) { - case 0: /* Long */ - fmovi_mrb (uae_p32(temp_fp), sreg, clamp_bounds.l); - mov_l_rm (S2, uae_p32(temp_fp)); - writelong_clobber (S1, S2, S3); - return 0; - case 1: /* Single */ - fmovs_mr (uae_p32(temp_fp), sreg); - mov_l_rm (S2, uae_p32(temp_fp)); - writelong_clobber (S1, S2, S3); - return 0; - case 2:/* Long Double */ - fmov_ext_mr (uae_p32(temp_fp), sreg); - mov_w_rm (S2, uae_p32(temp_fp) + 8); - writeword_clobber (S1, S2, S3); - add_l_ri (S1, 4); - mov_l_rm (S2, uae_p32(temp_fp) + 4); - writelong_clobber (S1, S2, S3); - add_l_ri (S1, 4); - mov_l_rm (S2, uae_p32(temp_fp)); - writelong_clobber (S1, S2, S3); - return 0; - case 4: /* Word */ - fmovi_mrb (uae_p32(temp_fp), sreg, clamp_bounds.w); - mov_l_rm (S2, uae_p32(temp_fp)); - writeword_clobber (S1, S2, S3); - return 0; - case 5: /* Double */ - fmov_mr (uae_p32(temp_fp), sreg); - mov_l_rm (S2, uae_p32(temp_fp) + 4); - writelong_clobber (S1, S2, S3); - add_l_ri (S1, 4); - mov_l_rm (S2, uae_p32(temp_fp)); - writelong_clobber (S1, S2, S3); - return 0; - case 6: /* Byte */ - fmovi_mrb (uae_p32(temp_fp), sreg, clamp_bounds.b); - mov_l_rm (S2, uae_p32(temp_fp)); - writebyte (S1, S2, S3); - return 0; - default: + + switch (size) + { + case 0: /* long */ + fmovi_mr((uintptr) temp_fp, val); + delay; + mov_l_rm(S2, (uintptr) temp_fp); + writelong_clobber(ad, S2, S3); + break; + case 1: /* single precision */ + fmovs_mr((uintptr) temp_fp, val); + delay; + mov_l_rm(S2, (uintptr) temp_fp); + writelong_clobber(ad, S2, S3); + break; + case 2: /* extended precision */ + fmov_ext_mr((uintptr) temp_fp, val); + delay; + mov_w_rm(S2, (uintptr) temp_fp + 8); + writeword_clobber(ad, S2, S3); + add_l_ri(ad, 4); + mov_l_rm(S2, (uintptr) temp_fp + 4); + writelong_clobber(ad, S2, S3); + add_l_ri(ad, 4); + mov_l_rm(S2, (uintptr) temp_fp); + writelong_clobber(ad, S2, S3); + break; + case 3: /* packed decimal static */ + return -1; /* Packed */ + case 4: /* word */ + fmovi_mr((uintptr) temp_fp, val); + delay; + mov_l_rm(S2, (uintptr) temp_fp); + writeword_clobber(ad, S2, S3); + break; + case 5: /* double precision */ + fmov_mr((uintptr) temp_fp, val); + delay; + mov_l_rm(S2, (uintptr) temp_fp + 4); + writelong_clobber(ad, S2, S3); + add_l_ri(ad, 4); + mov_l_rm(S2, (uintptr) temp_fp); + writelong_clobber(ad, S2, S3); + break; + case 6: /* byte */ + fmovi_mr((uintptr) temp_fp, val); + delay; + mov_l_rm(S2, (uintptr) temp_fp); + writebyte(ad, S2, S3); + break; + default: return -1; } - return -1; + return 0; } + /* return -1 for failure, or register number for success */ -STATIC_INLINE int comp_fp_adr (uae_u32 opcode) +STATIC_INLINE int get_fp_ad(uae_u32 opcode) { + int mode; + int reg; uae_s32 off; - int mode = (opcode >> 3) & 7; - int reg = opcode & 7; - - switch (mode) { - case 2: - case 3: - case 4: - mov_l_rr (S1, 8 + reg); + + mode = (opcode >> 3) & 7; + reg = opcode & 7; + switch (mode) + { + case 0: /* Dn */ + case 1: /* An */ + return -1; + case 2: /* (An) */ + case 3: /* (An)+ */ + case 4: /* -(An) */ + mov_l_rr(S1, 8 + reg); return S1; - case 5: - off = (uae_s32) (uae_s16) comp_get_iword ((m68k_pc_offset += 2) - 2); - mov_l_rr (S1, 8 + reg); - add_l_ri (S1, off); + case 5: /* d16(An) */ + off = (uae_s32) (uae_s16) comp_get_iword((m68k_pc_offset += 2) - 2); + mov_l_rr(S1, 8 + reg); + add_l_ri(S1, off); return S1; - case 7: - switch (reg) { - case 0: - off = (uae_s32) (uae_s16) comp_get_iword ((m68k_pc_offset += 2) - 2); - mov_l_ri (S1, off); + case 6: /* d8(An,Xn) */ + return -1; + break; + case 7: + switch (reg) + { + case 0: /* abs.w */ + off = (uae_s32) (uae_s16) comp_get_iword((m68k_pc_offset += 2) - 2); + mov_l_ri(S1, off); return S1; - case 1: - off = comp_get_ilong ((m68k_pc_offset += 4) - 4); - mov_l_ri (S1, off); + case 1: /* abs.l */ + off = comp_get_ilong((m68k_pc_offset += 4) - 4); + mov_l_ri(S1, off); return S1; - } + case 2: /* d16(pc) */ + off = start_pc + ((char *) comp_pc_p - (char *) start_pc_p) + m68k_pc_offset; + off += (uae_s32) (uae_s16) comp_get_iword((m68k_pc_offset += 2) - 2); + mov_l_ri(S1, off); + return S1; + case 3: /* d8(pc,Xn) */ + return -1; default: - return -1; + return -1; + } } + abort(); } -void comp_fdbcc_opp (uae_u32 opcode, uae_u16 extra) + +/* return -1 for failure, or register number for success */ +void comp_fdbcc_opp (uae_u32 /* opcode */, uae_u16 /* extra */) { - FAIL (1); - return; + if (jit_disable.fdbcc) + { + FAIL(1); + return; + } + FAIL(1); + return; } -void comp_fscc_opp (uae_u32 opcode, uae_u16 extra) + +void comp_fscc_opp(uae_u32 opcode, uae_u16 extra) { int reg; - if (!currprefs.compfpu) { - FAIL (1); + if (jit_disable.fscc) + { + FAIL(1); return; } -#if DEBUG_FPP - write_log (_T("JIT: fscc_opp at %08lx\n"), M68K_GETPC); -#endif - - if (extra & 0x20) { /* only cc from 00 to 1f are defined */ - FAIL (1); + if (extra & 0x20) + { /* only cc from 00 to 1f are defined */ + FAIL(1); return; } - if ((opcode & 0x38) != 0) { /* We can only do to integer register */ - FAIL (1); + if ((opcode & 0x38) != 0) + { /* We can only do to integer register */ + FAIL(1); return; } - fflags_into_flags (S2); + fflags_into_flags(S2); reg = (opcode & 7); - mov_l_ri (S1, 255); - mov_l_ri (S4, 0); - switch (extra & 0x0f) { /* according to fpp.c, the 0x10 bit is ignored */ - case 0: break; /* set never */ - case 1: mov_l_rr (S2, S4); - cmov_l_rr (S4, S1, 4); - cmov_l_rr (S4, S2, 10); break; - case 2: cmov_l_rr (S4, S1, 7); break; - case 3: cmov_l_rr (S4, S1, 3); break; - case 4: mov_l_rr (S2, S4); - cmov_l_rr (S4, S1, 2); - cmov_l_rr (S4, S2, 10); break; - case 5: mov_l_rr (S2, S4); - cmov_l_rr (S4, S1, 6); - cmov_l_rr (S4, S2, 10); break; - case 6: cmov_l_rr (S4, S1, 5); break; - case 7: cmov_l_rr (S4, S1, 11); break; - case 8: cmov_l_rr (S4, S1, 10); break; - case 9: cmov_l_rr (S4, S1, 4); break; - case 10: cmov_l_rr (S4, S1, 10); cmov_l_rr (S4, S1, 7); break; - case 11: cmov_l_rr (S4, S1, 4); cmov_l_rr (S4, S1, 3); break; - case 12: cmov_l_rr (S4, S1, 2); break; - case 13: cmov_l_rr (S4, S1, 6); break; - case 14: cmov_l_rr (S4, S1, 5); cmov_l_rr (S4, S1, 10); break; - case 15: mov_l_rr (S4, S1); break; + mov_l_ri(S1, 255); + mov_l_ri(S4, 0); + switch (extra & 0x0f) + { /* according to fpp.c, the 0x10 bit is ignored + */ + case 0: + break; /* set never */ + case 1: + mov_l_rr(S2, S4); + cmov_l_rr(S4, S1, 4); + cmov_l_rr(S4, S2, 10); + break; + case 2: + cmov_l_rr(S4, S1, 7); + break; + case 3: + cmov_l_rr(S4, S1, 3); + break; + case 4: + mov_l_rr(S2, S4); + cmov_l_rr(S4, S1, 2); + cmov_l_rr(S4, S2, 10); + break; + case 5: + mov_l_rr(S2, S4); + cmov_l_rr(S4, S1, 6); + cmov_l_rr(S4, S2, 10); + break; + case 6: + cmov_l_rr(S4, S1, 5); + break; + case 7: + cmov_l_rr(S4, S1, 11); + break; + case 8: + cmov_l_rr(S4, S1, 10); + break; + case 9: + cmov_l_rr(S4, S1, 4); + break; + case 10: + cmov_l_rr(S4, S1, 10); + cmov_l_rr(S4, S1, 7); + break; + case 11: + cmov_l_rr(S4, S1, 4); + cmov_l_rr(S4, S1, 3); + break; + case 12: + cmov_l_rr(S4, S1, 2); + break; + case 13: + cmov_l_rr(S4, S1, 6); + break; + case 14: + cmov_l_rr(S4, S1, 5); + cmov_l_rr(S4, S1, 10); + break; + case 15: + mov_l_rr(S4, S1); + break; } - if (!(opcode & 0x38)) - mov_b_rr (reg, S4); -#if 0 - else { + if ((opcode & 0x38) == 0) + { + mov_b_rr(reg, S4); + } else + { abort(); - if (!comp_fp_adr (opcode)) { - m68k_setpc (m68k_getpc () - 4); - op_illg (opcode); +#if 0 + int cc; + + if (get_fp_ad(opcode) < 0) + { + FAIL(1); + } else + { + put_byte(ad, cc ? 0xff : 0x00); } - else - put_byte (ad, cc ? 0xff : 0x00); - } #endif + } } -void comp_ftrapcc_opp (uae_u32 opcode, uaecptr oldpc) + +void comp_ftrapcc_opp (uae_u32 /* opcode */, uaecptr /* oldpc */) { - FAIL (1); + FAIL(1); return; } -extern unsigned long foink3, oink; -void comp_fbcc_opp (uae_u32 opcode) +void comp_fbcc_opp(uae_u32 opcode) { uae_u32 start_68k_offset = m68k_pc_offset; - uae_u32 off, v1, v2; + uae_u32 off; + uae_u32 v1; + uae_u32 v2; int cc; - if (!currprefs.compfpu) { - FAIL (1); - return; - } - // comp_pc_p is expected to be bound to 32-bit addresses assert((uintptr) comp_pc_p <= 0xffffffffUL); - if (opcode & 0x20) { /* only cc from 00 to 1f are defined */ - FAIL (1); + if (jit_disable.fbcc) + { + FAIL(1); return; } - if (!(opcode & 0x40)) { - off = (uae_s32) (uae_s16) comp_get_iword ((m68k_pc_offset += 2) - 2); + if (opcode & 0x20) + { /* only cc from 00 to 1f are defined */ + FAIL(1); + return; } - else { - off = comp_get_ilong ((m68k_pc_offset += 4) - 4); + if ((opcode & 0x40) == 0) + { + off = (uae_s32) (uae_s16) comp_get_iword((m68k_pc_offset += 2) - 2); + } else + { + off = comp_get_ilong((m68k_pc_offset += 4) - 4); } - - /* Note, "off" will sometimes be (unsigned) "negative", so the following - * uintptr can be > 0xffffffff, but the result will be correct due to - * wraparound when truncated to 32 bit in the call to mov_l_ri. */ - mov_l_ri(S1, (uintptr) - (comp_pc_p + off - (m68k_pc_offset - start_68k_offset))); + mov_l_ri(S1, (uintptr) (comp_pc_p + off - (m68k_pc_offset - start_68k_offset))); mov_l_ri(PC_P, (uintptr) comp_pc_p); /* Now they are both constant. Might as well fold in m68k_pc_offset */ - add_l_ri (S1, m68k_pc_offset); - add_l_ri (PC_P, m68k_pc_offset); + add_l_ri(S1, m68k_pc_offset); + add_l_ri(PC_P, m68k_pc_offset); m68k_pc_offset = 0; /* according to fpp.c, the 0x10 bit is ignored (it handles exception handling, which we don't do, anyway ;-) */ cc = opcode & 0x0f; - v1 = get_const (PC_P); - v2 = get_const (S1); - fflags_into_flags (S2); - - // mov_l_mi((uae_u32)&foink3,cc); - switch (cc) { - case 0: break; /* jump never */ - case 1: - mov_l_rr (S2, PC_P); - cmov_l_rr (PC_P, S1, 4); - cmov_l_rr (PC_P, S2, 10); break; - case 2: register_branch (v1, v2, 7); break; - case 3: register_branch (v1, v2, 3); break; - case 4: - mov_l_rr (S2, PC_P); - cmov_l_rr (PC_P, S1, 2); - cmov_l_rr (PC_P, S2, 10); break; - case 5: - mov_l_rr (S2, PC_P); - cmov_l_rr (PC_P, S1, 6); - cmov_l_rr (PC_P, S2, 10); break; - case 6: register_branch (v1, v2, 5); break; - case 7: register_branch (v1, v2, 11); break; - case 8: register_branch (v1, v2, 10); break; - case 9: register_branch (v1, v2, 4); break; - case 10: - cmov_l_rr (PC_P, S1, 10); - cmov_l_rr (PC_P, S1, 7); break; - case 11: - cmov_l_rr (PC_P, S1, 4); - cmov_l_rr (PC_P, S1, 3); break; - case 12: register_branch (v1, v2, 2); break; - case 13: register_branch (v1, v2, 6); break; - case 14: - cmov_l_rr (PC_P, S1, 5); - cmov_l_rr (PC_P, S1, 10); break; - case 15: mov_l_rr (PC_P, S1); break; + v1 = get_const(PC_P); + v2 = get_const(S1); + fflags_into_flags(S2); + + switch (cc) + { + case 0: + break; /* jump never */ + case 1: + mov_l_rr(S2, PC_P); + cmov_l_rr(PC_P, S1, 4); + cmov_l_rr(PC_P, S2, 10); + break; + case 2: + register_branch(v1, v2, 7); + break; + case 3: + register_branch(v1, v2, 3); + break; + case 4: + mov_l_rr(S2, PC_P); + cmov_l_rr(PC_P, S1, 2); + cmov_l_rr(PC_P, S2, 10); + break; + case 5: + mov_l_rr(S2, PC_P); + cmov_l_rr(PC_P, S1, 6); + cmov_l_rr(PC_P, S2, 10); + break; + case 6: + register_branch(v1, v2, 5); + break; + case 7: + register_branch(v1, v2, 11); + break; + case 8: + register_branch(v1, v2, 10); + break; + case 9: + register_branch(v1, v2, 4); + break; + case 10: + cmov_l_rr(PC_P, S1, 10); + cmov_l_rr(PC_P, S1, 7); + break; + case 11: + cmov_l_rr(PC_P, S1, 4); + cmov_l_rr(PC_P, S1, 3); + break; + case 12: + register_branch(v1, v2, 2); + break; + case 13: + register_branch(v1, v2, 6); + break; + case 14: + cmov_l_rr(PC_P, S1, 5); + cmov_l_rr(PC_P, S1, 10); + break; + case 15: + mov_l_rr(PC_P, S1); + break; } } -/* Floating point conditions - The "NotANumber" part could be problematic; However, when NaN is - encountered, the ftst instruction sets bot N and Z to 1 on the x87, - so quite often things just fall into place. This is probably not - accurate wrt the 68k FPU, but it is *as* accurate as this was before. - However, some more thought should go into fixing this stuff up so - it accurately emulates the 68k FPU. - >====> 7) & 7; - int source = (extra >> 13) & 7; - int opmode = extra & 0x7f; + uae_u32 d; + int incr = (opcode & 0x38) == 0x20 ? -1 : 1; + int ad; - if (!currprefs.compfpu) { - FAIL (1); + if (jit_disable.frestore) + { + FAIL(1); return; } - switch (source) { - case 3: /* FMOVE FPx, */ - if (comp_fp_put (opcode, extra) < 0) - FAIL (1); + FAIL(1); + return; + + if ((ad = get_fp_ad(opcode)) < 0) + { + FAIL(1); return; - case 4: /* FMOVE.L , ControlReg */ - if (!(opcode & 0x30)) { /* Dn or An */ - if (extra & 0x1000) { /* FPCR */ - mov_l_mr (uae_p32(®s.fpcr), opcode & 15); -#if USE_X86_FPUCW - mov_l_rr (S1, opcode & 15); - and_l_ri (S1, 0xf0); - fldcw_m_indexed (S1, uae_p32(x86_fpucw)); -#endif - return; - } - if (extra & 0x0800) { /* FPSR */ - FAIL (1); - return; - // set_fpsr(m68k_dreg (regs, opcode & 15)); + } + if (currprefs.fpu_model == 68040) + { + /* 68040 */ + if (incr < 0) + { + /* @@@ This may be wrong. */ + ad -= 4; + d = get_long(ad); + if ((d & 0xff000000) != 0) + { /* Not a NULL frame? */ + if ((d & 0x00ff0000) == 0) + { /* IDLE */ + } else if ((d & 0x00ff0000) == 0x00300000) + { /* UNIMP */ + ad -= 44; + } else if ((d & 0x00ff0000) == 0x00600000) + { /* BUSY */ + ad -= 92; + } } - if (extra & 0x0400) { /* FPIAR */ - mov_l_mr (uae_p32(®s.fpiar), opcode & 15); return; + } else + { + d = get_long(ad); + ad += 4; + if ((d & 0xff000000) != 0) + { /* Not a NULL frame? */ + if ((d & 0x00ff0000) == 0) + { /* IDLE */ + } else if ((d & 0x00ff0000) == 0x00300000) + { /* UNIMP */ + ad += 44; + } else if ((d & 0x00ff0000) == 0x00600000) + { /* BUSY */ + ad += 92; + } } } - else if ((opcode & 0x3f) == 0x3c) { - if (extra & 0x1000) { /* FPCR */ - uae_u32 val = comp_get_ilong ((m68k_pc_offset += 4) - 4); - mov_l_mi (uae_p32(®s.fpcr), val); -#if USE_X86_FPUCW - mov_l_ri (S1, val & 0xf0); - fldcw_m_indexed (S1, uae_p32(x86_fpucw)); -#endif - return; + } else + { + if (incr < 0) + { + ad -= 4; + d = get_long(ad); + if ((d & 0xff000000) != 0) + { + if ((d & 0x00ff0000) == 0x00180000) + ad -= 6 * 4; + else if ((d & 0x00ff0000) == 0x00380000) + ad -= 14 * 4; + else if ((d & 0x00ff0000) == 0x00b40000) + ad -= 45 * 4; } - if (extra & 0x0800) { /* FPSR */ - FAIL (1); - return; - } - if (extra & 0x0400) { /* FPIAR */ - uae_u32 val = comp_get_ilong ((m68k_pc_offset += 4) - 4); - mov_l_mi (uae_p32(®s.fpiar), val); - return; + } else + { + d = get_long(ad); + ad += 4; + if ((d & 0xff000000) != 0) + { + if ((d & 0x00ff0000) == 0x00180000) + ad += 6 * 4; + else if ((d & 0x00ff0000) == 0x00380000) + ad += 14 * 4; + else if ((d & 0x00ff0000) == 0x00b40000) + ad += 45 * 4; } } - FAIL (1); - return; - case 5: /* FMOVE.L ControlReg, */ - if (!(opcode & 0x30)) { /* Dn or An */ - if (extra & 0x1000) { /* FPCR */ - mov_l_rm (opcode & 15, uae_p32(®s.fpcr)); return; - } - if (extra & 0x0800) { /* FPSR */ - FAIL (1); - return; - } - if (extra & 0x0400) { /* FPIAR */ - mov_l_rm (opcode & 15, uae_p32(®s.fpiar)); return; - } + } + if ((opcode & 0x38) == 0x18) + m68k_areg(regs, opcode & 7) = ad; + if ((opcode & 0x38) == 0x20) + m68k_areg(regs, opcode & 7) = ad; +} +#endif + +#if defined(USE_LONG_DOUBLE) || defined(USE_QUAD_DOUBLE) +static const fpu_register const_e = LD(2.7182818284590452353); // LD(2.7182818284590452353602874713526625); +static const fpu_register const_log10_e = LD(0.4342944819032518276511289189166051); +static const fpu_register const_loge_10 = LD(2.3025850929940456840179914546843642); +#else +static const fpu_register const_e = 2.7182818284590452354; +static const fpu_register const_log10_e = 0.43429448190325182765; +static const fpu_register const_loge_10 = 2.30258509299404568402; +#endif + +static const fpu_register power10[] = { + LD(1e0), LD(1e1), LD(1e2), LD(1e4), LD(1e8), LD(1e16), LD(1e32), LD(1e64), LD(1e128), LD(1e256) +#if defined(USE_LONG_DOUBLE) || defined(USE_QUAD_DOUBLE) +, LD(1e512), LD(1e1024), LD(1e2048), LD(1e4096) +#endif +}; + +/* 128 words, indexed through the low byte of the 68k fpu control word */ +#if 1 +/* unused*/ +static uae_u16 x86_fpucw[]={ + 0x137f, 0x137f, 0x137f, 0x137f, 0x137f, 0x137f, 0x137f, 0x137f, /* p0r0 */ + 0x1f7f, 0x1f7f, 0x1f7f, 0x1f7f, 0x1f7f, 0x1f7f, 0x1f7f, 0x1f7f, /* p0r1 */ + 0x177f, 0x177f, 0x177f, 0x177f, 0x177f, 0x177f, 0x177f, 0x177f, /* p0r2 */ + 0x1b7f, 0x1b7f, 0x1b7f, 0x1b7f, 0x1b7f, 0x1b7f, 0x1b7f, 0x1b7f, /* p0r3 */ + + 0x107f, 0x107f, 0x107f, 0x107f, 0x107f, 0x107f, 0x107f, 0x107f, /* p1r0 */ + 0x1c7f, 0x1c7f, 0x1c7f, 0x1c7f, 0x1c7f, 0x1c7f, 0x1c7f, 0x1c7f, /* p1r1 */ + 0x147f, 0x147f, 0x147f, 0x147f, 0x147f, 0x147f, 0x147f, 0x147f, /* p1r2 */ + 0x187f, 0x187f, 0x187f, 0x187f, 0x187f, 0x187f, 0x187f, 0x187f, /* p1r3 */ + + 0x127f, 0x127f, 0x127f, 0x127f, 0x127f, 0x127f, 0x127f, 0x127f, /* p2r0 */ + 0x1e7f, 0x1e7f, 0x1e7f, 0x1e7f, 0x1e7f, 0x1e7f, 0x1e7f, 0x1e7f, /* p2r1 */ + 0x167f, 0x167f, 0x167f, 0x167f, 0x167f, 0x167f, 0x167f, 0x167f, /* p2r2 */ + 0x1a7f, 0x1a7f, 0x1a7f, 0x1a7f, 0x1a7f, 0x1a7f, 0x1a7f, 0x1a7f, /* p2r3 */ + + 0x137f, 0x137f, 0x137f, 0x137f, 0x137f, 0x137f, 0x137f, 0x137f, /* p3r0 */ + 0x1f7f, 0x1f7f, 0x1f7f, 0x1f7f, 0x1f7f, 0x1f7f, 0x1f7f, 0x1f7f, /* p3r1 */ + 0x177f, 0x177f, 0x177f, 0x177f, 0x177f, 0x177f, 0x177f, 0x177f, /* p3r2 */ + 0x1b7f, 0x1b7f, 0x1b7f, 0x1b7f, 0x1b7f, 0x1b7f, 0x1b7f, 0x1b7f /* p3r3 */ +}; +#endif + + +void comp_fpp_opp(uae_u32 opcode, uae_u16 extra) +{ + int reg; + int src; + + switch ((extra >> 13) & 0x7) + { + case 1: /* illegal */ + break; + + case 3: /* FMOVE Fpn, */ + /* 2nd most common */ + if (jit_disable.fmove) + { + FAIL(1); + return; + } + + if (put_fp_value((extra >> 7) & 7, opcode, extra) < 0) + { + FAIL(1); + return; } - FAIL (1); return; - case 6: - case 7: + + case 6: /* FMOVEM , */ + case 7: /* FMOVEM , */ + if (jit_disable.fmovem) { + FAIL(1); + return; + } + + { + int ad; uae_u32 list = 0; int incr = 0; - if (extra & 0x2000) { - int ad; + if (extra & 0x2000) + { /* FMOVEM FPP->memory */ - switch ((extra >> 11) & 3) { /* Get out early if failure */ - case 0: - case 2: + switch ((extra >> 11) & 3) + { /* Get out early if failure */ + case 0: /* static pred */ + case 2: /* static postinc */ break; - case 1: - case 3: - default: - FAIL (1); return; + case 1: /* dynamic pred */ + case 3: /* dynamic postinc */ + default: + FAIL(1); + return; } - ad = comp_fp_adr (opcode); - if (ad < 0) { - m68k_setpc (m68k_getpc () - 4); - op_illg (opcode); + if ((ad = get_fp_ad(opcode)) < 0) + { + FAIL(1); return; } - switch ((extra >> 11) & 3) { - case 0: /* static pred */ + switch ((extra >> 11) & 3) + { + case 0: /* static pred */ list = extra & 0xff; incr = -1; break; - case 2: /* static postinc */ + case 2: /* static postinc */ list = extra & 0xff; incr = 1; break; - case 1: /* dynamic pred */ - case 3: /* dynamic postinc */ - abort (); + case 1: /* dynamic pred */ + case 3: /* dynamic postinc */ + abort(); } - if (incr < 0) { /* Predecrement */ - for (reg = 7; reg >= 0; reg--) { - if (list & 0x80) { - fmov_ext_mr ((uintptr) temp_fp, reg); - sub_l_ri (ad, 4); - mov_l_rm (S2, (uintptr) temp_fp); - writelong_clobber (ad, S2, S3); - sub_l_ri (ad, 4); - mov_l_rm (S2, (uintptr) temp_fp + 4); - writelong_clobber (ad, S2, S3); - sub_l_ri (ad, 4); - mov_w_rm (S2, (uintptr) temp_fp + 8); - writeword_clobber (ad, S2, S3); + if (incr < 0) + { /* Predecrement */ + for (reg = 7; reg >= 0; reg--) + { + if (list & 0x80) + { + fmov_ext_mr((uintptr) temp_fp, reg); + delay; + sub_l_ri(ad, 4); + mov_l_rm(S2, (uintptr) temp_fp); + writelong_clobber(ad, S2, S3); + sub_l_ri(ad, 4); + mov_l_rm(S2, (uintptr) temp_fp + 4); + writelong_clobber(ad, S2, S3); + sub_l_ri(ad, 4); + mov_w_rm(S2, (uintptr) temp_fp + 8); + writeword_clobber(ad, S2, S3); } list <<= 1; } - } else { /* Postincrement */ - for (reg = 0; reg <= 7; reg++) { - if (list & 0x80) { - fmov_ext_mr ((uintptr) temp_fp, reg); - mov_w_rm (S2, (uintptr) temp_fp + 8); - writeword_clobber (ad, S2, S3); - add_l_ri (ad, 4); - mov_l_rm (S2, (uintptr) temp_fp + 4); - writelong_clobber (ad, S2, S3); - add_l_ri (ad, 4); - mov_l_rm (S2, (uintptr) temp_fp); - writelong_clobber (ad, S2, S3); - add_l_ri (ad, 4); + } else + { /* Postincrement */ + for (reg = 0; reg < 8; reg++) + { + if (list & 0x80) + { + fmov_ext_mr((uintptr) temp_fp, reg); + delay; + mov_w_rm(S2, (uintptr) temp_fp + 8); + writeword_clobber(ad, S2, S3); + add_l_ri(ad, 4); + mov_l_rm(S2, (uintptr) temp_fp + 4); + writelong_clobber(ad, S2, S3); + add_l_ri(ad, 4); + mov_l_rm(S2, (uintptr) temp_fp); + writelong_clobber(ad, S2, S3); + add_l_ri(ad, 4); } list <<= 1; } } if ((opcode & 0x38) == 0x18) - mov_l_rr ((opcode & 7) + 8, ad); + mov_l_rr((opcode & 7) + 8, ad); if ((opcode & 0x38) == 0x20) - mov_l_rr ((opcode & 7) + 8, ad); - } else { + mov_l_rr((opcode & 7) + 8, ad); + } else + { /* FMOVEM memory->FPP */ int ad; - switch ((extra >> 11) & 3) { /* Get out early if failure */ - case 0: - case 2: + + switch ((extra >> 11) & 3) + { /* Get out early if failure */ + case 0: /* static pred */ + case 2: /* static postinc */ break; - case 1: - case 3: - default: - FAIL (1); return; + case 1: /* dynamic pred */ + case 3: /* dynamic postinc */ + default: + FAIL(1); + return; } - ad = comp_fp_adr (opcode); - if (ad < 0) { - m68k_setpc (m68k_getpc () - 4); - op_illg (opcode); + ad = get_fp_ad(opcode); + if (ad < 0) + { + D(bug("no ad\n")); + FAIL(1); return; } - switch ((extra >> 11) & 3) { - case 0: /* static pred */ + switch ((extra >> 11) & 3) + { + case 0: /* static pred */ list = extra & 0xff; incr = -1; break; - case 2: /* static postinc */ + case 2: /* static postinc */ list = extra & 0xff; incr = 1; break; - case 1: /* dynamic pred */ - case 3: /* dynamic postinc */ - abort (); + case 1: /* dynamic pred */ + case 3: /* dynamic postinc */ + abort(); } - if (incr < 0) { + if (incr < 0) + { // not reached - for (reg = 7; reg >= 0; reg--) { - if (list & 0x80) { - sub_l_ri (ad, 4); - readlong (ad, S2, S3); - mov_l_mr ((uintptr) (temp_fp), S2); - sub_l_ri (ad, 4); - readlong (ad, S2, S3); - mov_l_mr ((uintptr) (temp_fp) +4, S2); - sub_l_ri (ad, 4); - readword (ad, S2, S3); - mov_w_mr (((uintptr) temp_fp) + 8, S2); - fmov_ext_rm (reg, (uintptr) (temp_fp)); + for (reg = 7; reg >= 0; reg--) + { + if (list & 0x80) + { + sub_l_ri(ad, 4); + readlong(ad, S2, S3); + mov_l_mr((uintptr) (temp_fp), S2); + sub_l_ri(ad, 4); + readlong(ad, S2, S3); + mov_l_mr((uintptr) (temp_fp) + 4, S2); + sub_l_ri(ad, 4); + readword(ad, S2, S3); + mov_w_mr(((uintptr) temp_fp) + 8, S2); + delay2; + fmov_ext_rm(reg, (uintptr) (temp_fp)); } list <<= 1; } - } else { - for (reg = 0; reg <= 7; reg++) { - if (list & 0x80) { - readword (ad, S2, S3); - mov_w_mr (((uintptr) temp_fp) + 8, S2); - add_l_ri (ad, 4); - readlong (ad, S2, S3); - mov_l_mr ((uintptr) (temp_fp) +4, S2); - add_l_ri (ad, 4); - readlong (ad, S2, S3); - mov_l_mr ((uintptr) (temp_fp), S2); - add_l_ri (ad, 4); - fmov_ext_rm (reg, (uintptr) (temp_fp)); + } else + { + for (reg = 0; reg < 8; reg++) + { + if (list & 0x80) + { + readword(ad, S2, S3); + mov_w_mr(((uintptr) temp_fp) + 8, S2); + add_l_ri(ad, 4); + readlong(ad, S2, S3); + mov_l_mr((uintptr) (temp_fp) + 4, S2); + add_l_ri(ad, 4); + readlong(ad, S2, S3); + mov_l_mr((uintptr) (temp_fp), S2); + add_l_ri(ad, 4); + delay2; + fmov_ext_rm(reg, (uintptr) (temp_fp)); } list <<= 1; } } if ((opcode & 0x38) == 0x18) - mov_l_rr ((opcode & 7) + 8, ad); + mov_l_rr((opcode & 7) + 8, ad); if ((opcode & 0x38) == 0x20) - mov_l_rr ((opcode & 7) + 8, ad); + mov_l_rr((opcode & 7) + 8, ad); } } return; -#if 0 - case 6: /* FMOVEM , FPx-FPz */ - if (!(extra & 0x0800)) { - uae_u32 list = extra & 0xff; - int ad; - if ((ad = comp_fp_adr(opcode)) < 0) {FAIL(1);return;} - while (list) { - if (extra & 0x1000) { /* postincrement */ - readword(ad,S2,S3); - mov_w_mr((uae_p32(temp_fp))+8,S2); - add_l_ri(ad,4); - readlong(ad,S2,S3); - mov_l_mr((uae_u32)(temp_fp)+4,S2); - add_l_ri(ad,4); - readlong(ad,S2,S3); - mov_l_mr((uae_u32)(temp_fp),S2); - add_l_ri(ad,4); - fmov_ext_rm(fpp_movem_index1[list],(uae_u32)(temp_fp)); - } else { /* predecrement */ - sub_l_ri(ad,4); - readlong(ad,S2,S3); - mov_l_mr((uae_u32)(temp_fp),S2); - sub_l_ri(ad,4); - readlong(ad,S2,S3); - mov_l_mr((uae_u32)(temp_fp)+4,S2); - sub_l_ri(ad,4); - readword(ad,S2,S3); - mov_w_mr((uae_p32(temp_fp))+8,S2); - fmov_ext_rm(fpp_movem_index2[list],(uae_u32)(temp_fp)); + + case 4: /* FMOVEM , */ + case 5: /* FMOVEM , */ + if (jit_disable.fmovec) + { + FAIL(1); + return; + } + + /* rare */ + if ((opcode & 0x30) == 0) + { + /* = Dn or An */ + if (extra & 0x2000) + { + if (extra & 0x1000) + { +#if HANDLE_FPCR + mov_l_rm(opcode & 15, (uintptr) & fpu.fpcr.rounding_mode); + or_l_rm(opcode & 15, (uintptr) & fpu.fpcr.rounding_precision); +#else + FAIL(1); + return; +#endif + } + if (extra & 0x0800) + { + FAIL(1); + return; + } + if (extra & 0x0400) + { + /* FPIAR: fixme; we cannot correctly return the address from compiled code */ +#ifdef UAE + mov_l_rm(opcode & 15, (uintptr)®s.fpiar); +#else + mov_l_rm(opcode & 15, (uintptr) & fpu.instruction_address); +#endif + return; } - list = fpp_movem_next[list]; + } else + { + // gb-- moved here so that we may FAIL() without generating any code + if (extra & 0x0800) + { + // set_fpsr(m68k_dreg (regs, opcode & 15)); + FAIL(1); + return; + } + if (extra & 0x1000) + { +#if HANDLE_FPCR +#if defined(FPU_USE_X86_ROUNDING_MODE) && defined(FPU_USE_X86_ROUNDING_PRECISION) + FAIL(1); + return; +#endif + mov_l_rr(S1, opcode & 15); + mov_l_rr(S2, opcode & 15); + and_l_ri(S1, FPCR_ROUNDING_PRECISION); + and_l_ri(S2, FPCR_ROUNDING_MODE); + mov_l_mr((uintptr) & fpu.fpcr.rounding_precision, S1); + mov_l_mr((uintptr) & fpu.fpcr.rounding_mode, S2); +#else + FAIL(1); + return; +#endif + } + if (extra & 0x0400) + { + /* FPIAR: does that make sense at all? */ +#ifdef UAE + mov_l_mr((uintptr)®s.fpiar, opcode & 15); +#else + mov_l_mr((uintptr) & fpu.instruction_address, opcode & 15); +#endif + } + return; } - if ((opcode & 0x38) == 0x18) - mov_l_rr((opcode & 7)+8,ad); - return; - } /* no break for dynamic register list */ - case 7: /* FMOVEM FPx-FPz, */ - if (!(extra & 0x0800)) { - uae_u32 list = extra & 0xff; - int ad; - if ((ad = comp_fp_adr(opcode)) < 0) {FAIL(1);return;} - while (list) { - if (extra & 0x1000) { /* postincrement */ - fmov_ext_mr(uae_p32(temp_fp),fpp_movem_index2[list]); - mov_w_rm(S2,uae_p32(temp_fp)+8); - writeword_clobber(ad,S2,S3); - add_l_ri(ad,4); - mov_l_rm(S2,uae_p32(temp_fp)+4); - writelong_clobber(ad,S2,S3); - add_l_ri(ad,4); - mov_l_rm(S2,uae_p32(temp_fp)); - writelong_clobber(ad,S2,S3); - add_l_ri(ad,4); - } else { /* predecrement */ - fmov_ext_mr(uae_p32(temp_fp),fpp_movem_index2[list]); - sub_l_ri(ad,4); - mov_l_rm(S2,uae_p32(temp_fp)); - writelong_clobber(ad,S2,S3); - sub_l_ri(ad,4); - mov_l_rm(S2,uae_p32(temp_fp)+4); - writelong_clobber(ad,S2,S3); - sub_l_ri(ad,4); - mov_w_rm(S2,uae_p32(temp_fp)+8); - writeword_clobber(ad,S2,S3); + } else if ((opcode & 0x3f) == 0x3c) + { + /* = #imm */ + if ((extra & 0x2000) == 0) + { + // gb-- moved here so that we may FAIL() without generating any code + if (extra & 0x0800) + { + FAIL(1); + return; + } + if (extra & 0x1000) + { + comp_get_ilong((m68k_pc_offset += 4) - 4); +#if HANDLE_FPCR +#if defined(FPU_USE_X86_ROUNDING_MODE) && defined(FPU_USE_X86_ROUNDING_PRECISION) + FAIL(1); + return; +#endif + // mov_l_mi((uintptr)®s.fpcr,val); + mov_l_ri(S1, val); + mov_l_ri(S2, val); + and_l_ri(S1, FPCR_ROUNDING_PRECISION); + and_l_ri(S2, FPCR_ROUNDING_MODE); + mov_l_mr((uintptr) & fpu.fpcr.rounding_precision, S1); + mov_l_mr((uintptr) & fpu.fpcr.rounding_mode, S2); +#else + FAIL(1); + return; +#endif + } + if (extra & 0x0400) + { + uae_u32 val = comp_get_ilong((m68k_pc_offset += 4) - 4); +#ifdef UAE + mov_l_mi((uintptr)®s.fpiar, val); +#else + mov_l_mi((uintptr) & fpu.instruction_address, val); +#endif } - list = fpp_movem_next[list]; + return; } - if ((opcode & 0x38) == 0x20) - mov_l_rr((opcode & 7)+8,ad); + FAIL(1); + return; + } else if (extra & 0x2000) + { + FAIL(1); + return; + } else + { + FAIL(1); return; - } /* no break */ - write_log (_T("fallback from JIT FMOVEM dynamic register list\n")); + } FAIL(1); return; -#endif - case 2: /* from to FPx */ - dont_care_fflags (); - if ((extra & 0xfc00) == 0x5c00) { /* FMOVECR */ - //write_log (_T("JIT FMOVECR %x\n"), opmode); - switch (opmode) { - case 0x00: - fmov_pi (dreg); - break; - case 0x0b: - fmov_ext_rm (dreg, uae_p32(&xhex_l10_2)); - break; - case 0x0c: - fmov_ext_rm (dreg, uae_p32(&xhex_exp_1)); - break; - case 0x0d: - fmov_log2_e (dreg); - break; - case 0x0e: - fmov_ext_rm (dreg, uae_p32(&xhex_l10_e)); - break; - case 0x0f: - fmov_0 (dreg); - break; - case 0x30: - fmov_loge_2 (dreg); - break; - case 0x31: - fmov_ext_rm (dreg, uae_p32(&xhex_ln_10)); - break; - case 0x32: - fmov_1 (dreg); - break; - case 0x33: - fmovs_rm (dreg, uae_p32(&fp_1e1)); - break; - case 0x34: - fmovs_rm (dreg, uae_p32(&fp_1e2)); - break; - case 0x35: - fmovs_rm (dreg, uae_p32(&fp_1e4)); - break; - case 0x36: - fmov_rm (dreg, uae_p32(&fp_1e8)); + + case 0: + case 2: /* Extremely common */ + reg = (extra >> 7) & 7; + if ((extra & 0xfc00) == 0x5c00) + { + if (jit_disable.fmovecr) + { + FAIL(1); + return; + } + + switch (extra & 0x7f) + { + case 0x00: + fmov_pi(reg); break; - case 0x37: - fmov_ext_rm (dreg, uae_p32(&xhex_1e16)); + case 0x0b: + fmov_log10_2(reg); break; - case 0x38: - fmov_ext_rm (dreg, uae_p32(&xhex_1e32)); + case 0x0c: +#if defined(USE_LONG_DOUBLE) || defined(USE_QUAD_DOUBLE) + fmov_ext_rm(reg, (uintptr) & const_e); +#else + fmov_rm(reg, (uintptr) & const_e); +#endif break; - case 0x39: - fmov_ext_rm (dreg, uae_p32(&xhex_1e64)); + case 0x0d: + fmov_log2_e(reg); break; - case 0x3a: - fmov_ext_rm (dreg, uae_p32(&xhex_1e128)); + case 0x0e: +#if defined(USE_LONG_DOUBLE) || defined(USE_QUAD_DOUBLE) + fmov_ext_rm(reg, (uintptr) & const_log10_e); +#else + fmov_rm(reg, (uintptr) & const_log10_e); +#endif break; - case 0x3b: - fmov_ext_rm (dreg, uae_p32(&xhex_1e256)); + case 0x0f: + fmov_0(reg); break; - case 0x3c: - fmov_ext_rm (dreg, uae_p32(&xhex_1e512)); + case 0x30: + fmov_loge_2(reg); break; - case 0x3d: - fmov_ext_rm (dreg, uae_p32(&xhex_1e1024)); + case 0x31: +#if defined(USE_LONG_DOUBLE) || defined(USE_QUAD_DOUBLE) + fmov_ext_rm(reg, (uintptr) & const_loge_10); +#else + fmov_rm(reg, (uintptr) & const_loge_10); +#endif break; - case 0x3e: - fmov_ext_rm (dreg, uae_p32(&xhex_1e2048)); + case 0x32: + fmov_1(reg); break; - case 0x3f: - fmov_ext_rm (dreg, uae_p32(&xhex_1e4096)); + case 0x33: + case 0x34: + case 0x35: + case 0x36: + case 0x37: + case 0x38: + case 0x39: + case 0x3a: + case 0x3b: +#if defined(USE_LONG_DOUBLE) || defined(USE_QUAD_DOUBLE) + case 0x3c: + case 0x3d: + case 0x3e: + case 0x3f: + fmov_ext_rm(reg, (uintptr) (power10 + (extra & 0x7f) - 0x32)); +#else + fmov_rm(reg, (uintptr) (power10 + (extra & 0x7f) - 0x32)); +#endif break; - default: - FAIL (1); + default: + /* This is not valid, so we fail */ + FAIL(1); return; } - fmov_rr (FP_RESULT, dreg); return; } - if (opmode & 0x20) /* two operands, so we need a scratch reg */ - sreg = FS1; - else /* one operand only, thus we can load the argument into dreg */ - sreg = dreg; - if ((prec = comp_fp_get (opcode, extra, sreg)) < 0) { - FAIL (1); - return; - } - if (!opmode) { /* FMOVE ,FPx */ - fmov_rr (FP_RESULT, dreg); - return; - } - /* no break here for to dreg */ - case 0: /* directly from sreg to dreg */ - if (!source) { /* no */ - dont_care_fflags (); - sreg = (extra >> 10) & 7; - } - switch (opmode) { - case 0x00: /* FMOVE */ - fmov_rr (dreg, sreg); + + switch (extra & 0x7f) + { + case 0x00: /* FMOVE */ + case 0x40: /* FSMOVE: Explicit rounding. This is just a quick fix. Same + * for all other cases that have three choices */ + case 0x44: /* FDMOVE */ + if (jit_disable.fmove) + { + FAIL(1); + return; + } + + dont_care_fflags(); + src = get_fp_value(opcode, extra); + if (src < 0) + { + FAIL(1); /* Illegal instruction */ + return; + } + fmov_rr(reg, src); + MAKE_FPSR(src); break; - case 0x01: /* FINT */ - frndint_rr (dreg, sreg); + case 0x01: /* FINT */ + if (jit_disable.fint) + { + FAIL(1); + return; + } + + FAIL(1); + return; + dont_care_fflags(); break; - case 0x02: /* FSINH */ - fsinh_rr (dreg, sreg); + case 0x02: /* FSINH */ + if (jit_disable.fsinh) + { + FAIL(1); + return; + } + + FAIL(1); + return; + dont_care_fflags(); break; - case 0x03: /* FINTRZ */ -#if USE_X86_FPUCW /* if we have control over the CW, we can do this */ - if (0 && (regs.fpcr & 0xf0) == 0x10) /* maybe unsafe, because this test is done */ - frndint_rr (dreg, sreg); /* during the JIT compilation and not at runtime */ - else { - mov_l_ri (S1, 0x10); /* extended round to zero */ - fldcw_m_indexed (S1, uae_p32(x86_fpucw)); - frndint_rr (dreg, sreg); - mov_l_rm (S1, uae_p32(®s.fpcr)); - and_l_ri (S1, 0xf0); /* restore control word */ - fldcw_m_indexed (S1, uae_p32(x86_fpucw)); + case 0x03: /* FINTRZ */ + if (jit_disable.fintrz) + { + FAIL(1); + return; } +#ifdef USE_X86_FPUCW + /* If we have control over the CW, we can do this */ + dont_care_fflags(); + src = get_fp_value(opcode, extra); + if (src < 0) + { + FAIL(1); /* Illegal instruction */ + return; + } + mov_l_ri(S1, 16); /* Switch to "round to zero" mode */ + fldcw_m_indexed(S1, (uintptr) x86_fpucw); + + frndint_rr(reg, src); + + /* restore control word */ + mov_l_rm(S1, (uintptr) & regs.fpcr); + and_l_ri(S1, 0x000000f0); + fldcw_m_indexed(S1, (uintptr) x86_fpucw); + + MAKE_FPSR(reg); break; #endif - FAIL (1); + FAIL(1); return; - case 0x04: /* FSQRT */ - fsqrt_rr (dreg, sreg); - break; - case 0x06: /* FLOGNP1 */ - flogNP1_rr (dreg, sreg); - break; - case 0x08: /* FETOXM1 */ - fetoxM1_rr (dreg, sreg); - break; - case 0x09: /* FTANH */ - ftanh_rr (dreg, sreg); - break; - case 0x0a: /* FATAN */ - fatan_rr (dreg, sreg); - break; - case 0x0c: /* FASIN */ - fasin_rr (dreg, sreg); break; - case 0x0d: /* FATANH */ - fatanh_rr (dreg, sreg); - break; - case 0x0e: /* FSIN */ - fsin_rr (dreg, sreg); - break; - case 0x0f: /* FTAN */ - ftan_rr (dreg, sreg); - break; - case 0x10: /* FETOX */ - fetox_rr (dreg, sreg); - break; - case 0x11: /* FTWOTOX */ - ftwotox_rr (dreg, sreg); - break; - case 0x12: /* FTENTOX */ - ftentox_rr (dreg, sreg); - break; - case 0x14: /* FLOGN */ - flogN_rr (dreg, sreg); + case 0x04: /* FSQRT */ + case 0x41: /* FSSQRT */ + case 0x45: /* FDSQRT */ + if (jit_disable.fsqrt) + { + FAIL(1); + return; + } + + dont_care_fflags(); + src = get_fp_value(opcode, extra); + if (src < 0) + { + FAIL(1); /* Illegal instruction */ + return; + } + fsqrt_rr(reg, src); + MAKE_FPSR(reg); break; - case 0x15: /* FLOG10 */ - flog10_rr (dreg, sreg); + case 0x06: /* FLOGNP1 */ + if (jit_disable.flognp1) + { + FAIL(1); + return; + } + + FAIL(1); + return; + dont_care_fflags(); break; - case 0x16: /* FLOG2 */ - flog2_rr (dreg, sreg); + case 0x08: /* FETOXM1 */ + if (jit_disable.fetoxm1) + { + FAIL(1); + return; + } + + FAIL(1); + return; + dont_care_fflags(); break; - case 0x18: /* FABS */ - fabs_rr (dreg, sreg); + case 0x09: /* FTANH */ + if (jit_disable.ftanh) + { + FAIL(1); + return; + } + + FAIL(1); + return; + dont_care_fflags(); break; - case 0x19: /* FCOSH */ - fcosh_rr (dreg, sreg); + case 0x0a: /* FATAN */ + if (jit_disable.fatan) + { + FAIL(1); + return; + } + + FAIL(1); + return; + dont_care_fflags(); break; - case 0x1a: /* FNEG */ - fneg_rr (dreg, sreg); + case 0x0c: /* FASIN */ + if (jit_disable.fasin) + { + FAIL(1); + return; + } + + FAIL(1); + return; + dont_care_fflags(); break; - case 0x1c: /* FACOS */ -#if USE_X86_FPUCW - mov_l_ri (S1, (regs.fpcr & 0xC0) | 0x00); - fldcw_m_indexed (S1, uae_p32(x86_fpucw)); - facos_rr (dreg, sreg); - mov_l_rm (S1, uae_p32(®s.fpcr)); - and_l_ri (S1, 0xf0); /* restore control word */ - fldcw_m_indexed (S1, uae_p32(x86_fpucw)); -#else - facos_rr (dreg, sreg); -#endif + case 0x0d: /* FATANH */ + if (jit_disable.fatanh) + { + FAIL(1); + return; + } + + FAIL(1); + return; + dont_care_fflags(); break; - case 0x1d: /* FCOS */ - fcos_rr (dreg, sreg); + case 0x0e: /* FSIN */ + if (jit_disable.fsin) + { + FAIL(1); + return; + } + + dont_care_fflags(); + src = get_fp_value(opcode, extra); + if (src < 0) + { + FAIL(1); /* Illegal instruction */ + return; + } + fsin_rr(reg, src); + MAKE_FPSR(reg); break; - case 0x1e: /* FGETEXP */ - fgetexp_rr (dreg, sreg); + case 0x0f: /* FTAN */ + if (jit_disable.ftan) + { + FAIL(1); + return; + } + + FAIL(1); + return; + dont_care_fflags(); break; - case 0x1f: /* FGETMAN */ - fgetman_rr (dreg, sreg); + case 0x10: /* FETOX */ + if (jit_disable.fetox) + { + FAIL(1); + return; + } + + dont_care_fflags(); + src = get_fp_value(opcode, extra); + if (src < 0) + { + FAIL(1); /* Illegal instruction */ + return; + } + fetox_rr(reg, src); + MAKE_FPSR(reg); break; - case 0x20: /* FDIV */ - fdiv_rr (dreg, sreg); + case 0x11: /* FTWOTOX */ + if (jit_disable.ftwotox) + { + FAIL(1); + return; + } + + dont_care_fflags(); + src = get_fp_value(opcode, extra); + if (src < 0) + { + FAIL(1); /* Illegal instruction */ + return; + } + ftwotox_rr(reg, src); + MAKE_FPSR(reg); break; - case 0x21: /* FMOD */ - frem_rr (dreg, sreg); + case 0x12: /* FTENTOX */ + if (jit_disable.ftentox) + { + FAIL(1); + return; + } + + FAIL(1); + return; + dont_care_fflags(); break; - case 0x22: /* FADD */ - fadd_rr (dreg, sreg); + case 0x14: /* FLOGN */ + if (jit_disable.flogn) + { + FAIL(1); + return; + } + + FAIL(1); + return; + dont_care_fflags(); break; - case 0x23: /* FMUL */ - fmul_rr (dreg, sreg); + case 0x15: /* FLOG10 */ + if (jit_disable.flog10) + { + FAIL(1); + return; + } + + FAIL(1); + return; + dont_care_fflags(); break; - case 0x24: /* FSGLDIV is not exactly the same as FSDIV, */ - /* because both operands should be SINGLE precision, too */ - case 0x60: /* FSDIV */ - fdiv_rr (dreg, sreg); - if (!currprefs.fpu_strict) /* faster, but less strict rounding */ - break; -#if USE_X86_FPUCW - if ((regs.fpcr & 0xC0) == 0x40) /* if SINGLE precision */ - break; -#endif - fcuts_r (dreg); + case 0x16: /* FLOG2 */ + if (jit_disable.flog2) + { + FAIL(1); + return; + } + + dont_care_fflags(); + src = get_fp_value(opcode, extra); + if (src < 0) + { + FAIL(1); /* Illegal instruction */ + return; + } + flog2_rr(reg, src); + MAKE_FPSR(reg); break; - case 0x25: /* FREM */ - frem1_rr (dreg, sreg); + case 0x18: /* FABS */ + case 0x58: /* FSABS */ + case 0x5c: /* FDABS */ + if (jit_disable.fabs) + { + FAIL(1); + return; + } + + dont_care_fflags(); + src = get_fp_value(opcode, extra); + if (src < 0) + { + FAIL(1); /* Illegal instruction */ + return; + } + fabs_rr(reg, src); + MAKE_FPSR(reg); break; - case 0x26: /* FSCALE */ - fscale_rr (dreg, sreg); + case 0x19: /* FCOSH */ + if (jit_disable.fcosh) + { + FAIL(1); + return; + } + + FAIL(1); + return; + dont_care_fflags(); break; - case 0x27: /* FSGLMUL is not exactly the same as FSMUL, */ - /* because both operands should be SINGLE precision, too */ - case 0x63: /* FSMUL */ - fmul_rr (dreg, sreg); - if (!currprefs.fpu_strict) /* faster, but less strict rounding */ - break; -#if USE_X86_FPUCW - if ((regs.fpcr & 0xC0) == 0x40) /* if SINGLE precision */ - break; -#endif - fcuts_r (dreg); + case 0x1a: /* FNEG */ + case 0x5a: /* FSNEG */ + case 0x5e: /* FDNEG */ + if (jit_disable.fneg) + { + FAIL(1); + return; + } + + dont_care_fflags(); + src = get_fp_value(opcode, extra); + if (src < 0) + { + FAIL(1); /* Illegal instruction */ + return; + } + fneg_rr(reg, src); + MAKE_FPSR(reg); break; - case 0x28: /* FSUB */ - fsub_rr (dreg, sreg); + case 0x1c: /* FACOS */ + if (jit_disable.facos) + { + FAIL(1); + return; + } + + FAIL(1); + return; + dont_care_fflags(); break; - case 0x30: /* FSINCOS */ - case 0x31: - case 0x32: - case 0x33: - case 0x34: - case 0x35: - case 0x36: - case 0x37: - if (dreg == (extra & 7)) - fsin_rr (dreg, sreg); - else - fsincos_rr (dreg, extra & 7, sreg); + case 0x1d: /* FCOS */ + if (jit_disable.fcos) + { + FAIL(1); + return; + } + + dont_care_fflags(); + src = get_fp_value(opcode, extra); + if (src < 0) + { + FAIL(1); /* Illegal instruction */ + return; + } + fcos_rr(reg, src); + MAKE_FPSR(reg); break; - case 0x38: /* FCMP */ - fmov_rr (FP_RESULT, dreg); - fsub_rr (FP_RESULT, sreg); + case 0x1e: /* FGETEXP */ + if (jit_disable.fgetexp) + { + FAIL(1); + return; + } + + FAIL(1); return; - case 0x3a: /* FTST */ - fmov_rr (FP_RESULT, sreg); + dont_care_fflags(); + break; + case 0x1f: /* FGETMAN */ + if (jit_disable.fgetman) + { + FAIL(1); + return; + } + + FAIL(1); return; - case 0x40: /* FSMOVE */ - if (prec == 1 || !currprefs.fpu_strict) { - if (sreg != dreg) /* no */ - fmov_rr (dreg, sreg); + dont_care_fflags(); + break; + case 0x20: /* FDIV */ + case 0x60: /* FSDIV */ + case 0x64: /* FDDIV */ + if (jit_disable.fdiv) + { + FAIL(1); + return; } - else { - fmovs_mr (uae_p32(temp_fp), sreg); - fmovs_rm (dreg, uae_p32(temp_fp)); + + dont_care_fflags(); + src = get_fp_value(opcode, extra); + if (src < 0) + { + FAIL(1); /* Illegal instruction */ + return; } + fdiv_rr(reg, src); + MAKE_FPSR(reg); break; - case 0x44: /* FDMOVE */ - if (prec || !currprefs.fpu_strict) { - if (sreg != dreg) /* no */ - fmov_rr (dreg, sreg); + case 0x21: /* FMOD */ + if (jit_disable.fmod) + { + FAIL(1); + return; } - else { - fmov_mr (uae_p32(temp_fp), sreg); - fmov_rm (dreg, uae_p32(temp_fp)); + + // FIXME: the quotient byte must be computed + dont_care_fflags(); + src = get_fp_value(opcode, extra); + if (src < 0) + { + FAIL(1); /* Illegal instruction */ + return; } + frem_rr(reg, src); + MAKE_FPSR(reg); break; - case 0x41: /* FSSQRT */ - fsqrt_rr (dreg, sreg); - if (!currprefs.fpu_strict) /* faster, but less strict rounding */ - break; -#if USE_X86_FPUCW - if ((regs.fpcr & 0xC0) == 0x40) /* if SINGLE precision */ - break; -#endif - fcuts_r (dreg); - break; - case 0x45: /* FDSQRT */ - if (!currprefs.fpu_strict) { /* faster, but less strict rounding */ - fsqrt_rr (dreg, sreg); - break; + case 0x22: /* FADD */ + case 0x62: /* FSADD */ + case 0x66: /* FDADD */ + if (jit_disable.fadd) + { + FAIL(1); + return; } -#if USE_X86_FPUCW - if (regs.fpcr & 0xC0) { /* if we don't have EXTENDED precision */ - if ((regs.fpcr & 0xC0) == 0x80) /* if we have DOUBLE */ - fsqrt_rr (dreg, sreg); - else { /* if we have SINGLE presision, force DOUBLE */ - mov_l_ri (S1, (regs.fpcr & 0x30) | 0x80); - fldcw_m_indexed (S1, uae_p32(x86_fpucw)); - fsqrt_rr (dreg, sreg); - mov_l_rm (S1, uae_p32(®s.fpcr)); - and_l_ri (S1, 0xf0); /* restore control word */ - fldcw_m_indexed (S1, uae_p32(x86_fpucw)); - } - break; + + dont_care_fflags(); + src = get_fp_value(opcode, extra); + if (src < 0) + { + FAIL(1); /* Illegal instruction */ + return; } -#endif /* in case of EXTENDED precision, just reduce the result to DOUBLE */ - fsqrt_rr (dreg, sreg); - fcut_r (dreg); + fadd_rr(reg, src); + MAKE_FPSR(reg); break; - case 0x58: /* FSABS */ - fabs_rr (dreg, sreg); - if (prec != 1 && currprefs.fpu_strict) - fcuts_r (dreg); - break; - case 0x5a: /* FSNEG */ - fneg_rr (dreg, sreg); - if (prec != 1 && currprefs.fpu_strict) - fcuts_r (dreg); + case 0x23: /* FMUL */ + case 0x63: /* FSMUL */ + case 0x67: /* FDMUL */ + if (jit_disable.fmul) + { + FAIL(1); + return; + } + + dont_care_fflags(); + src = get_fp_value(opcode, extra); + if (src < 0) + { + FAIL(1); /* Illegal instruction */ + return; + } + fmul_rr(reg, src); + MAKE_FPSR(reg); break; - case 0x5c: /* FDABS */ - fabs_rr (dreg, sreg); - if (!prec && currprefs.fpu_strict) - fcut_r (dreg); + case 0x24: /* FSGLDIV */ + if (jit_disable.fsgldiv) + { + FAIL(1); + return; + } + + dont_care_fflags(); + src = get_fp_value(opcode, extra); + if (src < 0) + { + FAIL(1); /* Illegal instruction */ + return; + } + fdiv_rr(reg, src); + MAKE_FPSR(reg); break; - case 0x5e: /* FDNEG */ - fneg_rr (dreg, sreg); - if (!prec && currprefs.fpu_strict) - fcut_r (dreg); + case 0x25: /* FREM */ + if (jit_disable.frem) + { + FAIL(1); + return; + } + // gb-- disabled because the quotient byte must be computed + // otherwise, free rotation in ClarisWorks doesn't work. + FAIL(1); + return; + dont_care_fflags(); + src = get_fp_value(opcode, extra); + if (src < 0) + { + FAIL(1); /* Illegal instruction */ + return; + } + frem1_rr(reg, src); + MAKE_FPSR(reg); break; - case 0x62: /* FSADD */ - fadd_rr (dreg, sreg); - if (!currprefs.fpu_strict) /* faster, but less strict rounding */ - break; -#if USE_X86_FPUCW - if ((regs.fpcr & 0xC0) == 0x40) /* if SINGLE precision */ - break; -#endif - fcuts_r (dreg); + case 0x26: /* FSCALE */ + if (jit_disable.fscale) + { + FAIL(1); + return; + } + + FAIL(1); + return; break; - case 0x64: /* FDDIV */ - if (!currprefs.fpu_strict) { /* faster, but less strict rounding */ - fdiv_rr (dreg, sreg); - break; + case 0x27: /* FSGLMUL */ + if (jit_disable.fsglmul) + { + FAIL(1); + return; } -#if USE_X86_FPUCW - if (regs.fpcr & 0xC0) { /* if we don't have EXTENDED precision */ - if ((regs.fpcr & 0xC0) == 0x80) /* if we have DOUBLE */ - fdiv_rr (dreg, sreg); - else { /* if we have SINGLE presision, force DOUBLE */ - mov_l_ri (S1, (regs.fpcr & 0x30) | 0x80); - fldcw_m_indexed (S1, uae_p32(x86_fpucw)); - fdiv_rr (dreg, sreg); - mov_l_rm (S1, uae_p32(®s.fpcr)); - and_l_ri (S1, 0xf0); /* restore control word */ - fldcw_m_indexed (S1, uae_p32(x86_fpucw)); - } - break; + + dont_care_fflags(); + src = get_fp_value(opcode, extra); + if (src < 0) + { + FAIL(1); /* Illegal instruction */ + return; } -#endif /* in case of EXTENDED precision, just reduce the result to DOUBLE */ - fdiv_rr (dreg, sreg); - fcut_r (dreg); + fmul_rr(reg, src); + MAKE_FPSR(reg); break; - case 0x66: /* FDADD */ - if (!currprefs.fpu_strict) { /* faster, but less strict rounding */ - fadd_rr (dreg, sreg); - break; + case 0x28: /* FSUB */ + case 0x68: /* FSSUB */ + case 0x6c: /* FDSUB */ + if (jit_disable.fsub) + { + FAIL(1); + return; } -#if USE_X86_FPUCW - if (regs.fpcr & 0xC0) { /* if we don't have EXTENDED precision */ - if ((regs.fpcr & 0xC0) == 0x80) /* if we have DOUBLE */ - fadd_rr (dreg, sreg); - else { /* if we have SINGLE presision, force DOUBLE */ - mov_l_ri (S1, (regs.fpcr & 0x30) | 0x80); - fldcw_m_indexed (S1, uae_p32(x86_fpucw)); - fadd_rr (dreg, sreg); - mov_l_rm (S1, uae_p32(®s.fpcr)); - and_l_ri (S1, 0xf0); /* restore control word */ - fldcw_m_indexed (S1, uae_p32(x86_fpucw)); - } - break; + + dont_care_fflags(); + src = get_fp_value(opcode, extra); + if (src < 0) + { + FAIL(1); /* Illegal instruction */ + return; } -#endif /* in case of EXTENDED precision, just reduce the result to DOUBLE */ - fadd_rr (dreg, sreg); - fcut_r (dreg); + fsub_rr(reg, src); + MAKE_FPSR(reg); break; - case 0x67: /* FDMUL */ - if (!currprefs.fpu_strict) { /* faster, but less strict rounding */ - fmul_rr (dreg, sreg); - break; - } -#if USE_X86_FPUCW - if (regs.fpcr & 0xC0) { /* if we don't have EXTENDED precision */ - if ((regs.fpcr & 0xC0) == 0x80) /* if we have DOUBLE */ - fmul_rr (dreg, sreg); - else { /* if we have SINGLE presision, force DOUBLE */ - mov_l_ri (S1, (regs.fpcr & 0x30) | 0x80); - fldcw_m_indexed (S1, uae_p32(x86_fpucw)); - fmul_rr (dreg, sreg); - mov_l_rm (S1, uae_p32(®s.fpcr)); - and_l_ri (S1, 0xf0); /* restore control word */ - fldcw_m_indexed (S1, uae_p32(x86_fpucw)); - } - break; + case 0x30: /* FSINCOS */ + case 0x31: + case 0x32: + case 0x33: + case 0x34: + case 0x35: + case 0x36: + case 0x37: + if (jit_disable.fsincos) + { + FAIL(1); + return; } -#endif /* in case of EXTENDED precision, just reduce the result to DOUBLE */ - fmul_rr (dreg, sreg); - fcut_r (dreg); + + FAIL(1); + return; + dont_care_fflags(); break; - case 0x68: /* FSSUB */ - fsub_rr (dreg, sreg); - if (!currprefs.fpu_strict) /* faster, but less strict rounding */ - break; -#if USE_X86_FPUCW - if ((regs.fpcr & 0xC0) == 0x40) /* if SINGLE precision */ - break; -#endif - fcuts_r (dreg); + case 0x38: /* FCMP */ + if (jit_disable.fcmp) + { + FAIL(1); + return; + } + + src = get_fp_value(opcode, extra); + if (src < 0) + { + FAIL(1); /* Illegal instruction */ + return; + } + fmov_rr(FP_RESULT, reg); + fsub_rr(FP_RESULT, src); /* Right way? */ break; - case 0x6c: /* FDSUB */ - if (!currprefs.fpu_strict) { /* faster, but less strict rounding */ - fsub_rr (dreg, sreg); - break; + case 0x3a: /* FTST */ + if (jit_disable.ftst) + { + FAIL(1); + return; } -#if USE_X86_FPUCW - if (regs.fpcr & 0xC0) { /* if we don't have EXTENDED precision */ - if ((regs.fpcr & 0xC0) == 0x80) /* if we have DOUBLE */ - fsub_rr (dreg, sreg); - else { /* if we have SINGLE presision, force DOUBLE */ - mov_l_ri (S1, (regs.fpcr & 0x30) | 0x80); - fldcw_m_indexed (S1, uae_p32(x86_fpucw)); - fsub_rr (dreg, sreg); - mov_l_rm (S1, uae_p32(®s.fpcr)); - and_l_ri (S1, 0xf0); /* restore control word */ - fldcw_m_indexed (S1, uae_p32(x86_fpucw)); - } - break; + + src = get_fp_value(opcode, extra); + if (src < 0) + { + FAIL(1); /* Illegal instruction */ + return; } -#endif /* in case of EXTENDED precision, just reduce the result to DOUBLE */ - fsub_rr (dreg, sreg); - fcut_r (dreg); + fmov_rr(FP_RESULT, src); break; - default: - FAIL (1); + default: + FAIL(1); return; + break; } - fmov_rr (FP_RESULT, dreg); - return; - default: - write_log (_T ("Unsupported JIT-FPU instruction: 0x%04x %04x\n"), opcode, extra); - FAIL (1); return; } + FAIL(1); } -#endif diff --git a/jit/compemu_midfunc_x86.cpp b/jit/compemu_midfunc_x86.cpp index 38e8bc93..afb99034 100644 --- a/jit/compemu_midfunc_x86.cpp +++ b/jit/compemu_midfunc_x86.cpp @@ -98,30 +98,28 @@ MIDFUNC(0,live_flags,(void)) live.flags_in_flags=VALID; live.flags_are_important=1; } -MENDFUNC(0,live_flags,(void)) MIDFUNC(0,dont_care_flags,(void)) { live.flags_are_important=0; } -MENDFUNC(0,dont_care_flags,(void)) +/* + * store the state of the x86 carry bit into regflags.x, + * into the position denoted by FLAGBIT_X + */ MIDFUNC(0,duplicate_carry,(void)) { evict(FLAGX); make_flags_live_internal(); -#ifdef UAE - COMPCALL(setcc_m)((uintptr)live.state[FLAGX].mem + 1, NATIVE_CC_CS); -#else COMPCALL(setcc_m)((uintptr)live.state[FLAGX].mem, NATIVE_CC_CS); -#endif log_vwrite(FLAGX); } -MENDFUNC(0,duplicate_carry,(void)) -MIDFUNC(0, setcc_for_cntzero, (RR4)) +MIDFUNC(3,setcc_for_cntzero,(RR4 /* cnt */, RR4 data, int size)) { - uae_u8 * branchadd; + uae_u8 *branchadd; + uae_u8 *branchadd2; evict(FLAGX); make_flags_live_internal(); @@ -135,64 +133,70 @@ MIDFUNC(0, setcc_for_cntzero, (RR4)) raw_jz_b_oponly(); branchadd = get_target(); skip_byte(); + + /* shift count was non-zero; update also x-flag */ raw_popfl(); - raw_pushfl(); -#ifdef UAE - COMPCALL(setcc_m)((uintptr)live.state[FLAGX].mem + 1, NATIVE_CC_CS); -#else COMPCALL(setcc_m)((uintptr)live.state[FLAGX].mem, NATIVE_CC_CS); -#endif log_vwrite(FLAGX); + raw_jmp_b_oponly(); + branchadd2 = get_target(); + skip_byte(); *branchadd = (uintptr)get_target() - ((uintptr)branchadd + 1); + + /* shift count was zero; need to set Z & N flags since the native flags were unaffected */ raw_popfl(); + data = readreg(data, size); + switch (size) + { + case 1: raw_test_b_rr(data, data); break; + case 2: raw_test_w_rr(data, data); break; + case 4: raw_test_l_rr(data, data); break; + } + unlock2(data); + *branchadd2 = (uintptr)get_target() - ((uintptr)branchadd2 + 1); } +/* + * Set the x86 carry flag from regflags.x, from the position + * denoted by FLAGBIT_X + */ MIDFUNC(0,restore_carry,(void)) { if (!have_rat_stall) { /* Not a P6 core, i.e. no partial stalls */ -#ifdef UAE - bt_l_ri_noclobber(FLAGX, 8); -#else - bt_l_ri_noclobber(FLAGX, 0); -#endif + bt_l_ri_noclobber(FLAGX, FLAGBIT_X); } else { /* Avoid the stall the above creates. This is slow on non-P6, though. */ -#ifdef UAE - COMPCALL(rol_w_ri(FLAGX, 8)); +#if FLAGBIT_X >= 8 + COMPCALL(rol_w_ri(FLAGX, 16 - FLAGBIT_X)); #else - COMPCALL(rol_b_ri(FLAGX, 8)); + COMPCALL(rol_b_ri(FLAGX, 8 - FLAGBIT_X)); #endif isclean(FLAGX); } } -MENDFUNC(0,restore_carry,(void)) MIDFUNC(0,start_needflags,(void)) { needflags=1; } -MENDFUNC(0,start_needflags,(void)) MIDFUNC(0,end_needflags,(void)) { needflags=0; } -MENDFUNC(0,end_needflags,(void)) MIDFUNC(0,make_flags_live,(void)) { make_flags_live_internal(); } -MENDFUNC(0,make_flags_live,(void)) MIDFUNC(1,fflags_into_flags,(W2 tmp)) { clobber_flags(); fflags_into_flags_internal(tmp); } -MENDFUNC(1,fflags_into_flags,(W2 tmp)) MIDFUNC(2,bt_l_ri,(RR4 r, IMM i)) /* This is defined as only affecting C */ { @@ -204,7 +208,6 @@ MIDFUNC(2,bt_l_ri,(RR4 r, IMM i)) /* This is defined as only affecting C */ raw_bt_l_ri(r,i); unlock2(r); } -MENDFUNC(2,bt_l_ri,(RR4 r, IMM i)) /* This is defined as only affecting C */ MIDFUNC(2,bt_l_rr,(RR4 r, RR4 b)) /* This is defined as only affecting C */ { @@ -215,7 +218,6 @@ MIDFUNC(2,bt_l_rr,(RR4 r, RR4 b)) /* This is defined as only affecting C */ unlock2(r); unlock2(b); } -MENDFUNC(2,bt_l_rr,(RR4 r, RR4 b)) /* This is defined as only affecting C */ MIDFUNC(2,btc_l_ri,(RW4 r, IMM i)) { @@ -227,7 +229,6 @@ MIDFUNC(2,btc_l_ri,(RW4 r, IMM i)) raw_btc_l_ri(r,i); unlock2(r); } -MENDFUNC(2,btc_l_ri,(RW4 r, IMM i)) MIDFUNC(2,btc_l_rr,(RW4 r, RR4 b)) { @@ -238,7 +239,6 @@ MIDFUNC(2,btc_l_rr,(RW4 r, RR4 b)) unlock2(r); unlock2(b); } -MENDFUNC(2,btc_l_rr,(RW4 r, RR4 b)) MIDFUNC(2,btr_l_ri,(RW4 r, IMM i)) { @@ -250,7 +250,6 @@ MIDFUNC(2,btr_l_ri,(RW4 r, IMM i)) raw_btr_l_ri(r,i); unlock2(r); } -MENDFUNC(2,btr_l_ri,(RW4 r, IMM i)) MIDFUNC(2,btr_l_rr,(RW4 r, RR4 b)) { @@ -261,7 +260,6 @@ MIDFUNC(2,btr_l_rr,(RW4 r, RR4 b)) unlock2(r); unlock2(b); } -MENDFUNC(2,btr_l_rr,(RW4 r, RR4 b)) MIDFUNC(2,bts_l_ri,(RW4 r, IMM i)) { @@ -273,7 +271,6 @@ MIDFUNC(2,bts_l_ri,(RW4 r, IMM i)) raw_bts_l_ri(r,i); unlock2(r); } -MENDFUNC(2,bts_l_ri,(RW4 r, IMM i)) MIDFUNC(2,bts_l_rr,(RW4 r, RR4 b)) { @@ -284,7 +281,6 @@ MIDFUNC(2,bts_l_rr,(RW4 r, RR4 b)) unlock2(r); unlock2(b); } -MENDFUNC(2,bts_l_rr,(RW4 r, RR4 b)) MIDFUNC(2,mov_l_rm,(W4 d, IMM s)) { @@ -293,7 +289,6 @@ MIDFUNC(2,mov_l_rm,(W4 d, IMM s)) raw_mov_l_rm(d,s); unlock2(d); } -MENDFUNC(2,mov_l_rm,(W4 d, IMM s)) MIDFUNC(1,call_r,(RR4 r)) /* Clobbering is implicit */ { @@ -303,35 +298,30 @@ MIDFUNC(1,call_r,(RR4 r)) /* Clobbering is implicit */ raw_inc_sp(STACK_SHADOW_SPACE); unlock2(r); } -MENDFUNC(1,call_r,(RR4 r)) /* Clobbering is implicit */ MIDFUNC(2,sub_l_mi,(IMM d, IMM s)) { CLOBBER_SUB; raw_sub_l_mi(d,s) ; } -MENDFUNC(2,sub_l_mi,(IMM d, IMM s)) MIDFUNC(2,mov_l_mi,(IMM d, IMM s)) { CLOBBER_MOV; raw_mov_l_mi(d,s) ; } -MENDFUNC(2,mov_l_mi,(IMM d, IMM s)) MIDFUNC(2,mov_w_mi,(IMM d, IMM s)) { CLOBBER_MOV; raw_mov_w_mi(d,s) ; } -MENDFUNC(2,mov_w_mi,(IMM d, IMM s)) MIDFUNC(2,mov_b_mi,(IMM d, IMM s)) { CLOBBER_MOV; raw_mov_b_mi(d,s) ; } -MENDFUNC(2,mov_b_mi,(IMM d, IMM s)) MIDFUNC(2,rol_b_ri,(RW1 r, IMM i)) { @@ -342,7 +332,6 @@ MIDFUNC(2,rol_b_ri,(RW1 r, IMM i)) raw_rol_b_ri(r,i); unlock2(r); } -MENDFUNC(2,rol_b_ri,(RW1 r, IMM i)) MIDFUNC(2,rol_w_ri,(RW2 r, IMM i)) { @@ -353,7 +342,6 @@ MIDFUNC(2,rol_w_ri,(RW2 r, IMM i)) raw_rol_w_ri(r,i); unlock2(r); } -MENDFUNC(2,rol_w_ri,(RW2 r, IMM i)) MIDFUNC(2,rol_l_ri,(RW4 r, IMM i)) { @@ -364,49 +352,46 @@ MIDFUNC(2,rol_l_ri,(RW4 r, IMM i)) raw_rol_l_ri(r,i); unlock2(r); } -MENDFUNC(2,rol_l_ri,(RW4 r, IMM i)) MIDFUNC(2,rol_l_rr,(RW4 d, RR1 r)) { - if (isconst(r)) { + if (isconst(r) && (uae_u8)live.state[r].val != 0) { COMPCALL(rol_l_ri)(d,(uae_u8)live.state[r].val); return; } CLOBBER_ROL; r=readreg_specific(r,1,SHIFTCOUNT_NREG); d=rmw(d,4,4); - Dif (r!=1) { - jit_abort("Illegal register %d in raw_rol_b",r); + Dif (r!=X86_CL) { + jit_abort("Illegal register %d in rol_l_rr",r); } raw_rol_l_rr(d,r) ; unlock2(r); unlock2(d); } -MENDFUNC(2,rol_l_rr,(RW4 d, RR1 r)) MIDFUNC(2,rol_w_rr,(RW2 d, RR1 r)) { /* Can only do this with r==1, i.e. cl */ - if (isconst(r)) { + if (isconst(r) && (uae_u8)live.state[r].val != 0) { COMPCALL(rol_w_ri)(d,(uae_u8)live.state[r].val); return; } CLOBBER_ROL; r=readreg_specific(r,1,SHIFTCOUNT_NREG); d=rmw(d,2,2); - Dif (r!=1) { - jit_abort("Illegal register %d in raw_rol_b",r); + Dif (r!=X86_CL) { + jit_abort("Illegal register %d in rol_w_rr",r); } raw_rol_w_rr(d,r) ; unlock2(r); unlock2(d); } -MENDFUNC(2,rol_w_rr,(RW2 d, RR1 r)) MIDFUNC(2,rol_b_rr,(RW1 d, RR1 r)) { /* Can only do this with r==1, i.e. cl */ - if (isconst(r)) { + if (isconst(r) && (uae_u8)live.state[r].val != 0) { COMPCALL(rol_b_ri)(d,(uae_u8)live.state[r].val); return; } @@ -414,57 +399,54 @@ MIDFUNC(2,rol_b_rr,(RW1 d, RR1 r)) CLOBBER_ROL; r=readreg_specific(r,1,SHIFTCOUNT_NREG); d=rmw(d,1,1); - Dif (r!=1) { - jit_abort("Illegal register %d in raw_rol_b",r); + Dif (r!=X86_CL) { + jit_abort("Illegal register %d in rol_b_rr",r); } raw_rol_b_rr(d,r) ; unlock2(r); unlock2(d); } -MENDFUNC(2,rol_b_rr,(RW1 d, RR1 r)) MIDFUNC(2,shll_l_rr,(RW4 d, RR1 r)) { - if (isconst(r)) { + if (isconst(r) && (uae_u8)live.state[r].val != 0) { COMPCALL(shll_l_ri)(d,(uae_u8)live.state[r].val); return; } CLOBBER_SHLL; r=readreg_specific(r,1,SHIFTCOUNT_NREG); d=rmw(d,4,4); - Dif (r!=1) { - jit_abort("Illegal register %d in raw_rol_b",r); + Dif (r!=X86_CL) { + jit_abort("Illegal register %d in shll_l_rr",r); } raw_shll_l_rr(d,r) ; unlock2(r); unlock2(d); } -MENDFUNC(2,shll_l_rr,(RW4 d, RR1 r)) MIDFUNC(2,shll_w_rr,(RW2 d, RR1 r)) { /* Can only do this with r==1, i.e. cl */ - if (isconst(r)) { + if (isconst(r) && (uae_u8)live.state[r].val != 0) { COMPCALL(shll_w_ri)(d,(uae_u8)live.state[r].val); return; } CLOBBER_SHLL; r=readreg_specific(r,1,SHIFTCOUNT_NREG); d=rmw(d,2,2); - Dif (r!=1) { - jit_abort("Illegal register %d in raw_shll_b",r); + Dif (r!=X86_CL) { + jit_abort("Illegal register %d in shll_w_rr",r); } raw_shll_w_rr(d,r) ; unlock2(r); unlock2(d); } -MENDFUNC(2,shll_w_rr,(RW2 d, RR1 r)) MIDFUNC(2,shll_b_rr,(RW1 d, RR1 r)) { /* Can only do this with r==1, i.e. cl */ - if (isconst(r)) { + if (isconst(r) && (uae_u8)live.state[r].val != 0) { COMPCALL(shll_b_ri)(d,(uae_u8)live.state[r].val); return; } @@ -472,14 +454,13 @@ MIDFUNC(2,shll_b_rr,(RW1 d, RR1 r)) CLOBBER_SHLL; r=readreg_specific(r,1,SHIFTCOUNT_NREG); d=rmw(d,1,1); - Dif (r!=1) { - jit_abort("Illegal register %d in raw_shll_b",r); + Dif (r!=X86_CL) { + jit_abort("Illegal register %d in shll_b_rr",r); } raw_shll_b_rr(d,r) ; unlock2(r); unlock2(d); } -MENDFUNC(2,shll_b_rr,(RW1 d, RR1 r)) MIDFUNC(2,ror_b_ri,(RR1 r, IMM i)) @@ -491,7 +472,6 @@ MIDFUNC(2,ror_b_ri,(RR1 r, IMM i)) raw_ror_b_ri(r,i); unlock2(r); } -MENDFUNC(2,ror_b_ri,(RR1 r, IMM i)) MIDFUNC(2,ror_w_ri,(RR2 r, IMM i)) { @@ -502,7 +482,6 @@ MIDFUNC(2,ror_w_ri,(RR2 r, IMM i)) raw_ror_w_ri(r,i); unlock2(r); } -MENDFUNC(2,ror_w_ri,(RR2 r, IMM i)) MIDFUNC(2,ror_l_ri,(RR4 r, IMM i)) { @@ -513,11 +492,10 @@ MIDFUNC(2,ror_l_ri,(RR4 r, IMM i)) raw_ror_l_ri(r,i); unlock2(r); } -MENDFUNC(2,ror_l_ri,(RR4 r, IMM i)) MIDFUNC(2,ror_l_rr,(RR4 d, RR1 r)) { - if (isconst(r)) { + if (isconst(r) && (uae_u8)live.state[r].val != 0) { COMPCALL(ror_l_ri)(d,(uae_u8)live.state[r].val); return; } @@ -528,11 +506,10 @@ MIDFUNC(2,ror_l_rr,(RR4 d, RR1 r)) unlock2(r); unlock2(d); } -MENDFUNC(2,ror_l_rr,(RR4 d, RR1 r)) MIDFUNC(2,ror_w_rr,(RR2 d, RR1 r)) { - if (isconst(r)) { + if (isconst(r) && (uae_u8)live.state[r].val != 0) { COMPCALL(ror_w_ri)(d,(uae_u8)live.state[r].val); return; } @@ -543,11 +520,10 @@ MIDFUNC(2,ror_w_rr,(RR2 d, RR1 r)) unlock2(r); unlock2(d); } -MENDFUNC(2,ror_w_rr,(RR2 d, RR1 r)) MIDFUNC(2,ror_b_rr,(RR1 d, RR1 r)) { - if (isconst(r)) { + if (isconst(r) && (uae_u8)live.state[r].val != 0) { COMPCALL(ror_b_ri)(d,(uae_u8)live.state[r].val); return; } @@ -559,49 +535,46 @@ MIDFUNC(2,ror_b_rr,(RR1 d, RR1 r)) unlock2(r); unlock2(d); } -MENDFUNC(2,ror_b_rr,(RR1 d, RR1 r)) MIDFUNC(2,shrl_l_rr,(RW4 d, RR1 r)) { - if (isconst(r)) { + if (isconst(r) && (uae_u8)live.state[r].val != 0) { COMPCALL(shrl_l_ri)(d,(uae_u8)live.state[r].val); return; } CLOBBER_SHRL; r=readreg_specific(r,1,SHIFTCOUNT_NREG); d=rmw(d,4,4); - Dif (r!=1) { - jit_abort("Illegal register %d in raw_rol_b",r); + Dif (r!=X86_CL) { + jit_abort("Illegal register %d in shrl_l_rr",r); } raw_shrl_l_rr(d,r) ; unlock2(r); unlock2(d); } -MENDFUNC(2,shrl_l_rr,(RW4 d, RR1 r)) MIDFUNC(2,shrl_w_rr,(RW2 d, RR1 r)) { /* Can only do this with r==1, i.e. cl */ - if (isconst(r)) { + if (isconst(r) && (uae_u8)live.state[r].val != 0) { COMPCALL(shrl_w_ri)(d,(uae_u8)live.state[r].val); return; } CLOBBER_SHRL; r=readreg_specific(r,1,SHIFTCOUNT_NREG); d=rmw(d,2,2); - Dif (r!=1) { - jit_abort("Illegal register %d in raw_shrl_b",r); + Dif (r!=X86_CL) { + jit_abort("Illegal register %d in shrl_w_rr",r); } raw_shrl_w_rr(d,r) ; unlock2(r); unlock2(d); } -MENDFUNC(2,shrl_w_rr,(RW2 d, RR1 r)) MIDFUNC(2,shrl_b_rr,(RW1 d, RR1 r)) { /* Can only do this with r==1, i.e. cl */ - if (isconst(r)) { + if (isconst(r) && (uae_u8)live.state[r].val != 0) { COMPCALL(shrl_b_ri)(d,(uae_u8)live.state[r].val); return; } @@ -609,14 +582,13 @@ MIDFUNC(2,shrl_b_rr,(RW1 d, RR1 r)) CLOBBER_SHRL; r=readreg_specific(r,1,SHIFTCOUNT_NREG); d=rmw(d,1,1); - Dif (r!=1) { - jit_abort("Illegal register %d in raw_shrl_b",r); + Dif (r!=X86_CL) { + jit_abort("Illegal register %d in shrl_b_rr",r); } raw_shrl_b_rr(d,r) ; unlock2(r); unlock2(d); } -MENDFUNC(2,shrl_b_rr,(RW1 d, RR1 r)) @@ -633,7 +605,6 @@ MIDFUNC(2,shll_l_ri,(RW4 r, IMM i)) raw_shll_l_ri(r,i); unlock2(r); } -MENDFUNC(2,shll_l_ri,(RW4 r, IMM i)) MIDFUNC(2,shll_w_ri,(RW2 r, IMM i)) { @@ -644,7 +615,6 @@ MIDFUNC(2,shll_w_ri,(RW2 r, IMM i)) raw_shll_w_ri(r,i); unlock2(r); } -MENDFUNC(2,shll_w_ri,(RW2 r, IMM i)) MIDFUNC(2,shll_b_ri,(RW1 r, IMM i)) { @@ -655,7 +625,6 @@ MIDFUNC(2,shll_b_ri,(RW1 r, IMM i)) raw_shll_b_ri(r,i); unlock2(r); } -MENDFUNC(2,shll_b_ri,(RW1 r, IMM i)) MIDFUNC(2,shrl_l_ri,(RW4 r, IMM i)) { @@ -670,7 +639,6 @@ MIDFUNC(2,shrl_l_ri,(RW4 r, IMM i)) raw_shrl_l_ri(r,i); unlock2(r); } -MENDFUNC(2,shrl_l_ri,(RW4 r, IMM i)) MIDFUNC(2,shrl_w_ri,(RW2 r, IMM i)) { @@ -681,7 +649,6 @@ MIDFUNC(2,shrl_w_ri,(RW2 r, IMM i)) raw_shrl_w_ri(r,i); unlock2(r); } -MENDFUNC(2,shrl_w_ri,(RW2 r, IMM i)) MIDFUNC(2,shrl_b_ri,(RW1 r, IMM i)) { @@ -692,7 +659,6 @@ MIDFUNC(2,shrl_b_ri,(RW1 r, IMM i)) raw_shrl_b_ri(r,i); unlock2(r); } -MENDFUNC(2,shrl_b_ri,(RW1 r, IMM i)) MIDFUNC(2,shra_l_ri,(RW4 r, IMM i)) { @@ -703,7 +669,6 @@ MIDFUNC(2,shra_l_ri,(RW4 r, IMM i)) raw_shra_l_ri(r,i); unlock2(r); } -MENDFUNC(2,shra_l_ri,(RW4 r, IMM i)) MIDFUNC(2,shra_w_ri,(RW2 r, IMM i)) { @@ -714,7 +679,6 @@ MIDFUNC(2,shra_w_ri,(RW2 r, IMM i)) raw_shra_w_ri(r,i); unlock2(r); } -MENDFUNC(2,shra_w_ri,(RW2 r, IMM i)) MIDFUNC(2,shra_b_ri,(RW1 r, IMM i)) { @@ -725,49 +689,46 @@ MIDFUNC(2,shra_b_ri,(RW1 r, IMM i)) raw_shra_b_ri(r,i); unlock2(r); } -MENDFUNC(2,shra_b_ri,(RW1 r, IMM i)) MIDFUNC(2,shra_l_rr,(RW4 d, RR1 r)) { - if (isconst(r)) { + if (isconst(r) && (uae_u8)live.state[r].val != 0) { COMPCALL(shra_l_ri)(d,(uae_u8)live.state[r].val); return; } CLOBBER_SHRA; r=readreg_specific(r,1,SHIFTCOUNT_NREG); d=rmw(d,4,4); - Dif (r!=1) { - jit_abort("Illegal register %d in raw_rol_b",r); + Dif (r!=X86_CL) { + jit_abort("Illegal register %d in shra_l_rr",r); } raw_shra_l_rr(d,r) ; unlock2(r); unlock2(d); } -MENDFUNC(2,shra_l_rr,(RW4 d, RR1 r)) MIDFUNC(2,shra_w_rr,(RW2 d, RR1 r)) { /* Can only do this with r==1, i.e. cl */ - if (isconst(r)) { + if (isconst(r) && (uae_u8)live.state[r].val != 0) { COMPCALL(shra_w_ri)(d,(uae_u8)live.state[r].val); return; } CLOBBER_SHRA; r=readreg_specific(r,1,SHIFTCOUNT_NREG); d=rmw(d,2,2); - Dif (r!=1) { - jit_abort("Illegal register %d in raw_shra_b",r); + Dif (r!=X86_CL) { + jit_abort("Illegal register %d in shra_w_rr",r); } raw_shra_w_rr(d,r) ; unlock2(r); unlock2(d); } -MENDFUNC(2,shra_w_rr,(RW2 d, RR1 r)) MIDFUNC(2,shra_b_rr,(RW1 d, RR1 r)) { /* Can only do this with r==1, i.e. cl */ - if (isconst(r)) { + if (isconst(r) && (uae_u8)live.state[r].val != 0) { COMPCALL(shra_b_ri)(d,(uae_u8)live.state[r].val); return; } @@ -775,14 +736,13 @@ MIDFUNC(2,shra_b_rr,(RW1 d, RR1 r)) CLOBBER_SHRA; r=readreg_specific(r,1,SHIFTCOUNT_NREG); d=rmw(d,1,1); - Dif (r!=1) { - jit_abort("Illegal register %d in raw_shra_b",r); + Dif (r!=X86_CL) { + jit_abort("Illegal register %d in shra_b_rr",r); } raw_shra_b_rr(d,r) ; unlock2(r); unlock2(d); } -MENDFUNC(2,shra_b_rr,(RW1 d, RR1 r)) MIDFUNC(2,setcc,(W1 d, IMM cc)) @@ -792,14 +752,12 @@ MIDFUNC(2,setcc,(W1 d, IMM cc)) raw_setcc(d,cc); unlock2(d); } -MENDFUNC(2,setcc,(W1 d, IMM cc)) MIDFUNC(2,setcc_m,(IMM d, IMM cc)) { CLOBBER_SETCC; raw_setcc_m(d,cc); } -MENDFUNC(2,setcc_m,(IMM d, IMM cc)) MIDFUNC(3,cmov_l_rr,(RW4 d, RR4 s, IMM cc)) { @@ -812,7 +770,6 @@ MIDFUNC(3,cmov_l_rr,(RW4 d, RR4 s, IMM cc)) unlock2(s); unlock2(d); } -MENDFUNC(3,cmov_l_rr,(RW4 d, RR4 s, IMM cc)) MIDFUNC(3,cmov_l_rm,(RW4 d, IMM s, IMM cc)) { @@ -821,7 +778,6 @@ MIDFUNC(3,cmov_l_rm,(RW4 d, IMM s, IMM cc)) raw_cmov_l_rm(d,s,cc); unlock2(d); } -MENDFUNC(3,cmov_l_rm,(RW4 d, IMM s, IMM cc)) MIDFUNC(2,bsf_l_rr,(W4 d, RR4 s)) { @@ -832,7 +788,6 @@ MIDFUNC(2,bsf_l_rr,(W4 d, RR4 s)) unlock2(s); unlock2(d); } -MENDFUNC(2,bsf_l_rr,(W4 d, RR4 s)) /* Set the Z flag depending on the value in s. Note that the value has to be 0 or -1 (or, more precisely, for non-zero @@ -846,7 +801,6 @@ MIDFUNC(2,simulate_bsf,(W4 tmp, RW4 s)) unlock2(tmp); unlock2(s); } -MENDFUNC(2,simulate_bsf,(W4 tmp, RW4 s)) MIDFUNC(2,imul_32_32,(RW4 d, RR4 s)) { @@ -857,7 +811,6 @@ MIDFUNC(2,imul_32_32,(RW4 d, RR4 s)) unlock2(s); unlock2(d); } -MENDFUNC(2,imul_32_32,(RW4 d, RR4 s)) MIDFUNC(2,imul_64_32,(RW4 d, RW4 s)) { @@ -868,7 +821,6 @@ MIDFUNC(2,imul_64_32,(RW4 d, RW4 s)) unlock2(s); unlock2(d); } -MENDFUNC(2,imul_64_32,(RW4 d, RW4 s)) MIDFUNC(2,mul_64_32,(RW4 d, RW4 s)) { @@ -879,7 +831,6 @@ MIDFUNC(2,mul_64_32,(RW4 d, RW4 s)) unlock2(s); unlock2(d); } -MENDFUNC(2,mul_64_32,(RW4 d, RW4 s)) MIDFUNC(2,mul_32_32,(RW4 d, RR4 s)) { @@ -890,7 +841,6 @@ MIDFUNC(2,mul_32_32,(RW4 d, RR4 s)) unlock2(s); unlock2(d); } -MENDFUNC(2,mul_32_32,(RW4 d, RR4 s)) #if SIZEOF_VOID_P == 8 MIDFUNC(2,sign_extend_32_rr,(W4 d, RR2 s)) @@ -921,7 +871,6 @@ MIDFUNC(2,sign_extend_32_rr,(W4 d, RR2 s)) unlock2(s); } } -MENDFUNC(2,sign_extend_32_rr,(W4 d, RR2 s)) #endif MIDFUNC(2,sign_extend_16_rr,(W4 d, RR2 s)) @@ -952,7 +901,6 @@ MIDFUNC(2,sign_extend_16_rr,(W4 d, RR2 s)) unlock2(s); } } -MENDFUNC(2,sign_extend_16_rr,(W4 d, RR2 s)) MIDFUNC(2,sign_extend_8_rr,(W4 d, RR1 s)) { @@ -984,7 +932,6 @@ MIDFUNC(2,sign_extend_8_rr,(W4 d, RR1 s)) unlock2(s); } } -MENDFUNC(2,sign_extend_8_rr,(W4 d, RR1 s)) MIDFUNC(2,zero_extend_16_rr,(W4 d, RR2 s)) @@ -1015,7 +962,6 @@ MIDFUNC(2,zero_extend_16_rr,(W4 d, RR2 s)) unlock2(s); } } -MENDFUNC(2,zero_extend_16_rr,(W4 d, RR2 s)) MIDFUNC(2,zero_extend_8_rr,(W4 d, RR1 s)) { @@ -1046,7 +992,6 @@ MIDFUNC(2,zero_extend_8_rr,(W4 d, RR1 s)) unlock2(s); } } -MENDFUNC(2,zero_extend_8_rr,(W4 d, RR1 s)) MIDFUNC(2,mov_b_rr,(W1 d, RR1 s)) { @@ -1064,7 +1009,6 @@ MIDFUNC(2,mov_b_rr,(W1 d, RR1 s)) unlock2(d); unlock2(s); } -MENDFUNC(2,mov_b_rr,(W1 d, RR1 s)) MIDFUNC(2,mov_w_rr,(W2 d, RR2 s)) { @@ -1082,7 +1026,6 @@ MIDFUNC(2,mov_w_rr,(W2 d, RR2 s)) unlock2(d); unlock2(s); } -MENDFUNC(2,mov_w_rr,(W2 d, RR2 s)) MIDFUNC(4,mov_l_rrm_indexed,(W4 d,RR4 baser, RR4 index, IMM factor)) { @@ -1096,7 +1039,6 @@ MIDFUNC(4,mov_l_rrm_indexed,(W4 d,RR4 baser, RR4 index, IMM factor)) unlock2(baser); unlock2(index); } -MENDFUNC(4,mov_l_rrm_indexed,(W4 d,RR4 baser, RR4 index, IMM factor)) MIDFUNC(4,mov_w_rrm_indexed,(W2 d, RR4 baser, RR4 index, IMM factor)) { @@ -1110,7 +1052,6 @@ MIDFUNC(4,mov_w_rrm_indexed,(W2 d, RR4 baser, RR4 index, IMM factor)) unlock2(baser); unlock2(index); } -MENDFUNC(4,mov_w_rrm_indexed,(W2 d, RR4 baser, RR4 index, IMM factor)) MIDFUNC(4,mov_b_rrm_indexed,(W1 d, RR4 baser, RR4 index, IMM factor)) { @@ -1125,7 +1066,6 @@ MIDFUNC(4,mov_b_rrm_indexed,(W1 d, RR4 baser, RR4 index, IMM factor)) unlock2(baser); unlock2(index); } -MENDFUNC(4,mov_b_rrm_indexed,(W1 d, RR4 baser, RR4 index, IMM factor)) MIDFUNC(4,mov_l_mrr_indexed,(RR4 baser, RR4 index, IMM factor, RR4 s)) @@ -1144,7 +1084,6 @@ MIDFUNC(4,mov_l_mrr_indexed,(RR4 baser, RR4 index, IMM factor, RR4 s)) unlock2(baser); unlock2(index); } -MENDFUNC(4,mov_l_mrr_indexed,(RR4 baser, RR4 index, IMM factor, RR4 s)) MIDFUNC(4,mov_w_mrr_indexed,(RR4 baser, RR4 index, IMM factor, RR2 s)) { @@ -1158,7 +1097,6 @@ MIDFUNC(4,mov_w_mrr_indexed,(RR4 baser, RR4 index, IMM factor, RR2 s)) unlock2(baser); unlock2(index); } -MENDFUNC(4,mov_w_mrr_indexed,(RR4 baser, RR4 index, IMM factor, RR2 s)) MIDFUNC(4,mov_b_mrr_indexed,(RR4 baser, RR4 index, IMM factor, RR1 s)) { @@ -1172,7 +1110,6 @@ MIDFUNC(4,mov_b_mrr_indexed,(RR4 baser, RR4 index, IMM factor, RR1 s)) unlock2(baser); unlock2(index); } -MENDFUNC(4,mov_b_mrr_indexed,(RR4 baser, RR4 index, IMM factor, RR1 s)) MIDFUNC(5,mov_l_bmrr_indexed,(IMM base, RR4 baser, RR4 index, IMM factor, RR4 s)) @@ -1193,7 +1130,6 @@ MIDFUNC(5,mov_l_bmrr_indexed,(IMM base, RR4 baser, RR4 index, IMM factor, RR4 s) unlock2(baser); unlock2(index); } -MENDFUNC(5,mov_l_bmrr_indexed,(IMM base, RR4 baser, RR4 index, IMM factor, RR4 s)) MIDFUNC(5,mov_w_bmrr_indexed,(IMM base, RR4 baser, RR4 index, IMM factor, RR2 s)) { @@ -1213,7 +1149,6 @@ MIDFUNC(5,mov_w_bmrr_indexed,(IMM base, RR4 baser, RR4 index, IMM factor, RR2 s) unlock2(baser); unlock2(index); } -MENDFUNC(5,mov_w_bmrr_indexed,(IMM base, RR4 baser, RR4 index, IMM factor, RR2 s)) MIDFUNC(5,mov_b_bmrr_indexed,(IMM base, RR4 baser, RR4 index, IMM factor, RR1 s)) { @@ -1233,7 +1168,6 @@ MIDFUNC(5,mov_b_bmrr_indexed,(IMM base, RR4 baser, RR4 index, IMM factor, RR1 s) unlock2(baser); unlock2(index); } -MENDFUNC(5,mov_b_bmrr_indexed,(IMM base, RR4 baser, RR4 index, IMM factor, RR1 s)) @@ -1254,7 +1188,6 @@ MIDFUNC(5,mov_l_brrm_indexed,(W4 d, IMM base, RR4 baser, RR4 index, IMM factor)) unlock2(baser); unlock2(index); } -MENDFUNC(5,mov_l_brrm_indexed,(W4 d, IMM base, RR4 baser, RR4 index, IMM factor)) MIDFUNC(5,mov_w_brrm_indexed,(W2 d, IMM base, RR4 baser, RR4 index, IMM factor)) @@ -1274,7 +1207,6 @@ MIDFUNC(5,mov_w_brrm_indexed,(W2 d, IMM base, RR4 baser, RR4 index, IMM factor)) unlock2(baser); unlock2(index); } -MENDFUNC(5,mov_w_brrm_indexed,(W2 d, IMM base, RR4 baser, RR4 index, IMM factor)) MIDFUNC(5,mov_b_brrm_indexed,(W1 d, IMM base, RR4 baser, RR4 index, IMM factor)) @@ -1294,7 +1226,6 @@ MIDFUNC(5,mov_b_brrm_indexed,(W1 d, IMM base, RR4 baser, RR4 index, IMM factor)) unlock2(baser); unlock2(index); } -MENDFUNC(5,mov_b_brrm_indexed,(W1 d, IMM base, RR4 baser, RR4 index, IMM factor)) /* Read a long from base+factor*index */ MIDFUNC(4,mov_l_rm_indexed,(W4 d, IMM base, RR4 index, IMM factor)) @@ -1315,7 +1246,6 @@ MIDFUNC(4,mov_l_rm_indexed,(W4 d, IMM base, RR4 index, IMM factor)) unlock2(index); unlock2(d); } -MENDFUNC(4,mov_l_rm_indexed,(W4 d, IMM base, RR4 index, IMM factor)) /* read the long at the address contained in s+offset and store in d */ MIDFUNC(3,mov_l_rR,(W4 d, RR4 s, IMM offset)) @@ -1332,7 +1262,6 @@ MIDFUNC(3,mov_l_rR,(W4 d, RR4 s, IMM offset)) unlock2(d); unlock2(s); } -MENDFUNC(3,mov_l_rR,(W4 d, RR4 s, IMM offset)) /* read the word at the address contained in s+offset and store in d */ MIDFUNC(3,mov_w_rR,(W2 d, RR4 s, IMM offset)) @@ -1349,7 +1278,6 @@ MIDFUNC(3,mov_w_rR,(W2 d, RR4 s, IMM offset)) unlock2(d); unlock2(s); } -MENDFUNC(3,mov_w_rR,(W2 d, RR4 s, IMM offset)) /* read the word at the address contained in s+offset and store in d */ MIDFUNC(3,mov_b_rR,(W1 d, RR4 s, IMM offset)) @@ -1366,7 +1294,6 @@ MIDFUNC(3,mov_b_rR,(W1 d, RR4 s, IMM offset)) unlock2(d); unlock2(s); } -MENDFUNC(3,mov_b_rR,(W1 d, RR4 s, IMM offset)) /* read the long at the address contained in s+offset and store in d */ MIDFUNC(3,mov_l_brR,(W4 d, RR4 s, IMM offset)) @@ -1385,7 +1312,6 @@ MIDFUNC(3,mov_l_brR,(W4 d, RR4 s, IMM offset)) unlock2(d); unlock2(s); } -MENDFUNC(3,mov_l_brR,(W4 d, RR4 s, IMM offset)) /* read the word at the address contained in s+offset and store in d */ MIDFUNC(3,mov_w_brR,(W2 d, RR4 s, IMM offset)) @@ -1405,7 +1331,6 @@ MIDFUNC(3,mov_w_brR,(W2 d, RR4 s, IMM offset)) unlock2(d); unlock2(s); } -MENDFUNC(3,mov_w_brR,(W2 d, RR4 s, IMM offset)) /* read the word at the address contained in s+offset and store in d */ MIDFUNC(3,mov_b_brR,(W1 d, RR4 s, IMM offset)) @@ -1425,7 +1350,6 @@ MIDFUNC(3,mov_b_brR,(W1 d, RR4 s, IMM offset)) unlock2(d); unlock2(s); } -MENDFUNC(3,mov_b_brR,(W1 d, RR4 s, IMM offset)) MIDFUNC(3,mov_l_Ri,(RR4 d, IMM i, IMM offset)) { @@ -1441,7 +1365,6 @@ MIDFUNC(3,mov_l_Ri,(RR4 d, IMM i, IMM offset)) raw_mov_l_Ri(d,i,offset); unlock2(d); } -MENDFUNC(3,mov_l_Ri,(RR4 d, IMM i, IMM offset)) MIDFUNC(3,mov_w_Ri,(RR4 d, IMM i, IMM offset)) { @@ -1457,7 +1380,6 @@ MIDFUNC(3,mov_w_Ri,(RR4 d, IMM i, IMM offset)) raw_mov_w_Ri(d,i,offset); unlock2(d); } -MENDFUNC(3,mov_w_Ri,(RR4 d, IMM i, IMM offset)) MIDFUNC(3,mov_b_Ri,(RR4 d, IMM i, IMM offset)) { @@ -1473,7 +1395,6 @@ MIDFUNC(3,mov_b_Ri,(RR4 d, IMM i, IMM offset)) raw_mov_b_Ri(d,i,offset); unlock2(d); } -MENDFUNC(3,mov_b_Ri,(RR4 d, IMM i, IMM offset)) /* Warning! OFFSET is byte sized only! */ MIDFUNC(3,mov_l_Rr,(RR4 d, RR4 s, IMM offset)) @@ -1495,7 +1416,6 @@ MIDFUNC(3,mov_l_Rr,(RR4 d, RR4 s, IMM offset)) unlock2(d); unlock2(s); } -MENDFUNC(3,mov_l_Rr,(RR4 d, RR4 s, IMM offset)) MIDFUNC(3,mov_w_Rr,(RR4 d, RR2 s, IMM offset)) { @@ -1515,7 +1435,6 @@ MIDFUNC(3,mov_w_Rr,(RR4 d, RR2 s, IMM offset)) unlock2(d); unlock2(s); } -MENDFUNC(3,mov_w_Rr,(RR4 d, RR2 s, IMM offset)) MIDFUNC(3,mov_b_Rr,(RR4 d, RR1 s, IMM offset)) { @@ -1535,7 +1454,6 @@ MIDFUNC(3,mov_b_Rr,(RR4 d, RR1 s, IMM offset)) unlock2(d); unlock2(s); } -MENDFUNC(3,mov_b_Rr,(RR4 d, RR1 s, IMM offset)) MIDFUNC(3,lea_l_brr,(W4 d, RR4 s, IMM offset)) { @@ -1556,7 +1474,6 @@ MIDFUNC(3,lea_l_brr,(W4 d, RR4 s, IMM offset)) unlock2(d); unlock2(s); } -MENDFUNC(3,lea_l_brr,(W4 d, RR4 s, IMM offset)) MIDFUNC(5,lea_l_brr_indexed,(W4 d, RR4 s, RR4 index, IMM factor, IMM offset)) { @@ -1574,7 +1491,6 @@ MIDFUNC(5,lea_l_brr_indexed,(W4 d, RR4 s, RR4 index, IMM factor, IMM offset)) unlock2(index); unlock2(s); } -MENDFUNC(5,lea_l_brr_indexed,(W4 d, RR4 s, RR4 index, IMM factor, IMM offset)) MIDFUNC(4,lea_l_rr_indexed,(W4 d, RR4 s, RR4 index, IMM factor)) { @@ -1588,7 +1504,6 @@ MIDFUNC(4,lea_l_rr_indexed,(W4 d, RR4 s, RR4 index, IMM factor)) unlock2(index); unlock2(s); } -MENDFUNC(4,lea_l_rr_indexed,(W4 d, RR4 s, RR4 index, IMM factor)) /* write d to the long at the address contained in s+offset */ MIDFUNC(3,mov_l_bRr,(RR4 d, RR4 s, IMM offset)) @@ -1608,7 +1523,6 @@ MIDFUNC(3,mov_l_bRr,(RR4 d, RR4 s, IMM offset)) unlock2(d); unlock2(s); } -MENDFUNC(3,mov_l_bRr,(RR4 d, RR4 s, IMM offset)) /* write the word at the address contained in s+offset and store in d */ MIDFUNC(3,mov_w_bRr,(RR4 d, RR2 s, IMM offset)) @@ -1628,7 +1542,6 @@ MIDFUNC(3,mov_w_bRr,(RR4 d, RR2 s, IMM offset)) unlock2(d); unlock2(s); } -MENDFUNC(3,mov_w_bRr,(RR4 d, RR2 s, IMM offset)) MIDFUNC(3,mov_b_bRr,(RR4 d, RR1 s, IMM offset)) { @@ -1646,7 +1559,6 @@ MIDFUNC(3,mov_b_bRr,(RR4 d, RR1 s, IMM offset)) unlock2(d); unlock2(s); } -MENDFUNC(3,mov_b_bRr,(RR4 d, RR1 s, IMM offset)) MIDFUNC(1,mid_bswap_32,(RW4 r)) { @@ -1662,7 +1574,6 @@ MIDFUNC(1,mid_bswap_32,(RW4 r)) raw_bswap_32(r); unlock2(r); } -MENDFUNC(1,mid_bswap_32,(RW4 r)) MIDFUNC(1,mid_bswap_16,(RW2 r)) { @@ -1678,7 +1589,6 @@ MIDFUNC(1,mid_bswap_16,(RW2 r)) raw_bswap_16(r); unlock2(r); } -MENDFUNC(1,mid_bswap_16,(RW2 r)) @@ -1709,7 +1619,6 @@ MIDFUNC(2,mov_l_rr,(W4 d, RR4 s)) jit_log2("Added %d to nreg %d(%d), now holds %d regs", d,s,live.state[d].realind,live.nat[s].nholds); unlock2(s); } -MENDFUNC(2,mov_l_rr,(W4 d, RR4 s)) MIDFUNC(2,mov_l_mr,(IMM d, RR4 s)) { @@ -1723,7 +1632,6 @@ MIDFUNC(2,mov_l_mr,(IMM d, RR4 s)) raw_mov_l_mr(d,s); unlock2(s); } -MENDFUNC(2,mov_l_mr,(IMM d, RR4 s)) MIDFUNC(2,mov_w_mr,(IMM d, RR2 s)) @@ -1738,7 +1646,6 @@ MIDFUNC(2,mov_w_mr,(IMM d, RR2 s)) raw_mov_w_mr(d,s); unlock2(s); } -MENDFUNC(2,mov_w_mr,(IMM d, RR2 s)) MIDFUNC(2,mov_w_rm,(W2 d, IMM s)) { @@ -1748,7 +1655,6 @@ MIDFUNC(2,mov_w_rm,(W2 d, IMM s)) raw_mov_w_rm(d,s); unlock2(d); } -MENDFUNC(2,mov_w_rm,(W2 d, IMM s)) MIDFUNC(2,mov_b_mr,(IMM d, RR1 s)) { @@ -1763,7 +1669,6 @@ MIDFUNC(2,mov_b_mr,(IMM d, RR1 s)) raw_mov_b_mr(d,s); unlock2(s); } -MENDFUNC(2,mov_b_mr,(IMM d, RR1 s)) MIDFUNC(2,mov_b_rm,(W1 d, IMM s)) { @@ -1773,14 +1678,12 @@ MIDFUNC(2,mov_b_rm,(W1 d, IMM s)) raw_mov_b_rm(d,s); unlock2(d); } -MENDFUNC(2,mov_b_rm,(W1 d, IMM s)) MIDFUNC(2,mov_l_ri,(W4 d, IMM s)) { set_const(d,s); return; } -MENDFUNC(2,mov_l_ri,(W4 d, IMM s)) MIDFUNC(2,mov_w_ri,(W2 d, IMM s)) { @@ -1790,7 +1693,6 @@ MIDFUNC(2,mov_w_ri,(W2 d, IMM s)) raw_mov_w_ri(d,s); unlock2(d); } -MENDFUNC(2,mov_w_ri,(W2 d, IMM s)) MIDFUNC(2,mov_b_ri,(W1 d, IMM s)) { @@ -1800,28 +1702,24 @@ MIDFUNC(2,mov_b_ri,(W1 d, IMM s)) raw_mov_b_ri(d,s); unlock2(d); } -MENDFUNC(2,mov_b_ri,(W1 d, IMM s)) MIDFUNC(2,add_l_mi,(IMM d, IMM s)) { CLOBBER_ADD; - raw_add_l_mi(d,s) ; + raw_add_l_mi(d,s); } -MENDFUNC(2,add_l_mi,(IMM d, IMM s)) MIDFUNC(2,add_w_mi,(IMM d, IMM s)) { CLOBBER_ADD; - raw_add_w_mi(d,s) ; + raw_add_w_mi(d,s); } -MENDFUNC(2,add_w_mi,(IMM d, IMM s)) MIDFUNC(2,add_b_mi,(IMM d, IMM s)) { CLOBBER_ADD; - raw_add_b_mi(d,s) ; + raw_add_b_mi(d,s); } -MENDFUNC(2,add_b_mi,(IMM d, IMM s)) MIDFUNC(2,test_l_ri,(RR4 d, IMM i)) { @@ -1831,7 +1729,6 @@ MIDFUNC(2,test_l_ri,(RR4 d, IMM i)) raw_test_l_ri(d,i); unlock2(d); } -MENDFUNC(2,test_l_ri,(RR4 d, IMM i)) MIDFUNC(2,test_l_rr,(RR4 d, RR4 s)) { @@ -1843,7 +1740,6 @@ MIDFUNC(2,test_l_rr,(RR4 d, RR4 s)) unlock2(d); unlock2(s); } -MENDFUNC(2,test_l_rr,(RR4 d, RR4 s)) MIDFUNC(2,test_w_rr,(RR2 d, RR2 s)) { @@ -1855,7 +1751,6 @@ MIDFUNC(2,test_w_rr,(RR2 d, RR2 s)) unlock2(d); unlock2(s); } -MENDFUNC(2,test_w_rr,(RR2 d, RR2 s)) MIDFUNC(2,test_b_rr,(RR1 d, RR1 s)) { @@ -1867,8 +1762,12 @@ MIDFUNC(2,test_b_rr,(RR1 d, RR1 s)) unlock2(d); unlock2(s); } -MENDFUNC(2,test_b_rr,(RR1 d, RR1 s)) +MIDFUNC(2,test_b_mi,(IMM d, IMM s)) +{ + CLOBBER_TEST; + raw_test_b_mi(d,s); +} MIDFUNC(2,and_l_ri,(RW4 d, IMM i)) { @@ -1883,7 +1782,6 @@ MIDFUNC(2,and_l_ri,(RW4 d, IMM i)) raw_and_l_ri(d,i); unlock2(d); } -MENDFUNC(2,and_l_ri,(RW4 d, IMM i)) MIDFUNC(2,and_l,(RW4 d, RR4 s)) { @@ -1895,7 +1793,6 @@ MIDFUNC(2,and_l,(RW4 d, RR4 s)) unlock2(d); unlock2(s); } -MENDFUNC(2,and_l,(RW4 d, RR4 s)) MIDFUNC(2,and_w,(RW2 d, RR2 s)) { @@ -1907,7 +1804,6 @@ MIDFUNC(2,and_w,(RW2 d, RR2 s)) unlock2(d); unlock2(s); } -MENDFUNC(2,and_w,(RW2 d, RR2 s)) MIDFUNC(2,and_b,(RW1 d, RR1 s)) { @@ -1919,7 +1815,6 @@ MIDFUNC(2,and_b,(RW1 d, RR1 s)) unlock2(d); unlock2(s); } -MENDFUNC(2,and_b,(RW1 d, RR1 s)) // gb-- used for making an fpcr value in compemu_fpp.cpp MIDFUNC(2,or_l_rm,(RW4 d, IMM s)) @@ -1930,7 +1825,6 @@ MIDFUNC(2,or_l_rm,(RW4 d, IMM s)) raw_or_l_rm(d,s); unlock2(d); } -MENDFUNC(2,or_l_rm,(RW4 d, IMM s)) MIDFUNC(2,or_l_ri,(RW4 d, IMM i)) { @@ -1944,7 +1838,6 @@ MIDFUNC(2,or_l_ri,(RW4 d, IMM i)) raw_or_l_ri(d,i); unlock2(d); } -MENDFUNC(2,or_l_ri,(RW4 d, IMM i)) MIDFUNC(2,or_l,(RW4 d, RR4 s)) { @@ -1960,7 +1853,6 @@ MIDFUNC(2,or_l,(RW4 d, RR4 s)) unlock2(d); unlock2(s); } -MENDFUNC(2,or_l,(RW4 d, RR4 s)) MIDFUNC(2,or_w,(RW2 d, RR2 s)) { @@ -1972,7 +1864,6 @@ MIDFUNC(2,or_w,(RW2 d, RR2 s)) unlock2(d); unlock2(s); } -MENDFUNC(2,or_w,(RW2 d, RR2 s)) MIDFUNC(2,or_b,(RW1 d, RR1 s)) { @@ -1984,7 +1875,6 @@ MIDFUNC(2,or_b,(RW1 d, RR1 s)) unlock2(d); unlock2(s); } -MENDFUNC(2,or_b,(RW1 d, RR1 s)) MIDFUNC(2,adc_l,(RW4 d, RR4 s)) { @@ -1997,7 +1887,6 @@ MIDFUNC(2,adc_l,(RW4 d, RR4 s)) unlock2(d); unlock2(s); } -MENDFUNC(2,adc_l,(RW4 d, RR4 s)) MIDFUNC(2,adc_w,(RW2 d, RR2 s)) { @@ -2009,7 +1898,6 @@ MIDFUNC(2,adc_w,(RW2 d, RR2 s)) unlock2(d); unlock2(s); } -MENDFUNC(2,adc_w,(RW2 d, RR2 s)) MIDFUNC(2,adc_b,(RW1 d, RR1 s)) { @@ -2021,7 +1909,6 @@ MIDFUNC(2,adc_b,(RW1 d, RR1 s)) unlock2(d); unlock2(s); } -MENDFUNC(2,adc_b,(RW1 d, RR1 s)) MIDFUNC(2,add_l,(RW4 d, RR4 s)) { @@ -2039,7 +1926,6 @@ MIDFUNC(2,add_l,(RW4 d, RR4 s)) unlock2(d); unlock2(s); } -MENDFUNC(2,add_l,(RW4 d, RR4 s)) MIDFUNC(2,add_w,(RW2 d, RR2 s)) { @@ -2056,7 +1942,6 @@ MIDFUNC(2,add_w,(RW2 d, RR2 s)) unlock2(d); unlock2(s); } -MENDFUNC(2,add_w,(RW2 d, RR2 s)) MIDFUNC(2,add_b,(RW1 d, RR1 s)) { @@ -2073,7 +1958,6 @@ MIDFUNC(2,add_b,(RW1 d, RR1 s)) unlock2(d); unlock2(s); } -MENDFUNC(2,add_b,(RW1 d, RR1 s)) MIDFUNC(2,sub_l_ri,(RW4 d, IMM i)) { @@ -2096,7 +1980,6 @@ MIDFUNC(2,sub_l_ri,(RW4 d, IMM i)) raw_sub_l_ri(d,i); unlock2(d); } -MENDFUNC(2,sub_l_ri,(RW4 d, IMM i)) MIDFUNC(2,sub_w_ri,(RW2 d, IMM i)) { @@ -2109,7 +1992,6 @@ MIDFUNC(2,sub_w_ri,(RW2 d, IMM i)) raw_sub_w_ri(d,i); unlock2(d); } -MENDFUNC(2,sub_w_ri,(RW2 d, IMM i)) MIDFUNC(2,sub_b_ri,(RW1 d, IMM i)) { @@ -2123,7 +2005,6 @@ MIDFUNC(2,sub_b_ri,(RW1 d, IMM i)) unlock2(d); } -MENDFUNC(2,sub_b_ri,(RW1 d, IMM i)) MIDFUNC(2,add_l_ri,(RW4 d, IMM i)) { @@ -2144,7 +2025,6 @@ MIDFUNC(2,add_l_ri,(RW4 d, IMM i)) raw_add_l_ri(d,i); unlock2(d); } -MENDFUNC(2,add_l_ri,(RW4 d, IMM i)) MIDFUNC(2,add_w_ri,(RW2 d, IMM i)) { @@ -2157,7 +2037,6 @@ MIDFUNC(2,add_w_ri,(RW2 d, IMM i)) raw_add_w_ri(d,i); unlock2(d); } -MENDFUNC(2,add_w_ri,(RW2 d, IMM i)) MIDFUNC(2,add_b_ri,(RW1 d, IMM i)) { @@ -2171,7 +2050,6 @@ MIDFUNC(2,add_b_ri,(RW1 d, IMM i)) unlock2(d); } -MENDFUNC(2,add_b_ri,(RW1 d, IMM i)) MIDFUNC(2,sbb_l,(RW4 d, RR4 s)) { @@ -2183,7 +2061,6 @@ MIDFUNC(2,sbb_l,(RW4 d, RR4 s)) unlock2(d); unlock2(s); } -MENDFUNC(2,sbb_l,(RW4 d, RR4 s)) MIDFUNC(2,sbb_w,(RW2 d, RR2 s)) { @@ -2195,7 +2072,6 @@ MIDFUNC(2,sbb_w,(RW2 d, RR2 s)) unlock2(d); unlock2(s); } -MENDFUNC(2,sbb_w,(RW2 d, RR2 s)) MIDFUNC(2,sbb_b,(RW1 d, RR1 s)) { @@ -2207,7 +2083,6 @@ MIDFUNC(2,sbb_b,(RW1 d, RR1 s)) unlock2(d); unlock2(s); } -MENDFUNC(2,sbb_b,(RW1 d, RR1 s)) MIDFUNC(2,sub_l,(RW4 d, RR4 s)) { @@ -2224,7 +2099,6 @@ MIDFUNC(2,sub_l,(RW4 d, RR4 s)) unlock2(d); unlock2(s); } -MENDFUNC(2,sub_l,(RW4 d, RR4 s)) MIDFUNC(2,sub_w,(RW2 d, RR2 s)) { @@ -2241,7 +2115,6 @@ MIDFUNC(2,sub_w,(RW2 d, RR2 s)) unlock2(d); unlock2(s); } -MENDFUNC(2,sub_w,(RW2 d, RR2 s)) MIDFUNC(2,sub_b,(RW1 d, RR1 s)) { @@ -2258,7 +2131,6 @@ MIDFUNC(2,sub_b,(RW1 d, RR1 s)) unlock2(d); unlock2(s); } -MENDFUNC(2,sub_b,(RW1 d, RR1 s)) MIDFUNC(2,cmp_l,(RR4 d, RR4 s)) { @@ -2270,7 +2142,6 @@ MIDFUNC(2,cmp_l,(RR4 d, RR4 s)) unlock2(d); unlock2(s); } -MENDFUNC(2,cmp_l,(RR4 d, RR4 s)) MIDFUNC(2,cmp_l_ri,(RR4 r, IMM i)) { @@ -2280,7 +2151,6 @@ MIDFUNC(2,cmp_l_ri,(RR4 r, IMM i)) raw_cmp_l_ri(r,i); unlock2(r); } -MENDFUNC(2,cmp_l_ri,(RR4 r, IMM i)) MIDFUNC(2,cmp_w,(RR2 d, RR2 s)) { @@ -2292,7 +2162,6 @@ MIDFUNC(2,cmp_w,(RR2 d, RR2 s)) unlock2(d); unlock2(s); } -MENDFUNC(2,cmp_w,(RR2 d, RR2 s)) MIDFUNC(2,cmp_b,(RR1 d, RR1 s)) { @@ -2304,7 +2173,6 @@ MIDFUNC(2,cmp_b,(RR1 d, RR1 s)) unlock2(d); unlock2(s); } -MENDFUNC(2,cmp_b,(RR1 d, RR1 s)) MIDFUNC(2,xor_l,(RW4 d, RR4 s)) @@ -2317,7 +2185,6 @@ MIDFUNC(2,xor_l,(RW4 d, RR4 s)) unlock2(d); unlock2(s); } -MENDFUNC(2,xor_l,(RW4 d, RR4 s)) MIDFUNC(2,xor_w,(RW2 d, RR2 s)) { @@ -2329,7 +2196,6 @@ MIDFUNC(2,xor_w,(RW2 d, RR2 s)) unlock2(d); unlock2(s); } -MENDFUNC(2,xor_w,(RW2 d, RR2 s)) MIDFUNC(2,xor_b,(RW1 d, RR1 s)) { @@ -2341,8 +2207,8 @@ MIDFUNC(2,xor_b,(RW1 d, RR1 s)) unlock2(d); unlock2(s); } -MENDFUNC(2,xor_b,(RW1 d, RR1 s)) +#ifdef UAE MIDFUNC(5,call_r_11,(W4 out1, RR4 r, RR4 in1, IMM osize, IMM isize)) { clobber_flags(); @@ -2388,8 +2254,9 @@ MIDFUNC(5,call_r_11,(W4 out1, RR4 r, RR4 in1, IMM osize, IMM isize)) live.state[out1].dirtysize=osize; set_status(out1,DIRTY); } -MENDFUNC(5,call_r_11,(W4 out1, RR4 r, RR4 in1, IMM osize, IMM isize)) +#endif +#if defined(UAE) MIDFUNC(5,call_r_02,(RR4 r, RR4 in1, RR4 in2, IMM isize1, IMM isize2)) { clobber_flags(); @@ -2415,7 +2282,7 @@ MIDFUNC(5,call_r_02,(RR4 r, RR4 in1, RR4 in2, IMM isize1, IMM isize2)) raw_inc_sp(8); #endif } -MENDFUNC(5,call_r_02,(RR4 r, RR4 in1, RR4 in2, IMM isize1, IMM isize2)) +#endif /* forget_about() takes a mid-layer register */ MIDFUNC(1,forget_about,(W4 r)) @@ -2425,13 +2292,11 @@ MIDFUNC(1,forget_about,(W4 r)) live.state[r].val=0; set_status(r,UNDEF); } -MENDFUNC(1,forget_about,(W4 r)) MIDFUNC(0,nop,(void)) { raw_emit_nop(); } -MENDFUNC(0,nop,(void)) MIDFUNC(1,f_forget_about,(FW r)) { @@ -2439,7 +2304,6 @@ MIDFUNC(1,f_forget_about,(FW r)) f_disassociate(r); live.fate[r].status=UNDEF; } -MENDFUNC(1,f_forget_about,(FW r)) MIDFUNC(1,fmov_pi,(FW r)) { @@ -2447,7 +2311,6 @@ MIDFUNC(1,fmov_pi,(FW r)) raw_fmov_pi(r); f_unlock(r); } -MENDFUNC(1,fmov_pi,(FW r)) MIDFUNC(1,fmov_log10_2,(FW r)) { @@ -2455,7 +2318,6 @@ MIDFUNC(1,fmov_log10_2,(FW r)) raw_fmov_log10_2(r); f_unlock(r); } -MENDFUNC(1,fmov_log10_2,(FW r)) MIDFUNC(1,fmov_log2_e,(FW r)) { @@ -2463,7 +2325,6 @@ MIDFUNC(1,fmov_log2_e,(FW r)) raw_fmov_log2_e(r); f_unlock(r); } -MENDFUNC(1,fmov_log2_e,(FW r)) MIDFUNC(1,fmov_loge_2,(FW r)) { @@ -2471,7 +2332,6 @@ MIDFUNC(1,fmov_loge_2,(FW r)) raw_fmov_loge_2(r); f_unlock(r); } -MENDFUNC(1,fmov_loge_2,(FW r)) MIDFUNC(1,fmov_1,(FW r)) { @@ -2479,7 +2339,6 @@ MIDFUNC(1,fmov_1,(FW r)) raw_fmov_1(r); f_unlock(r); } -MENDFUNC(1,fmov_1,(FW r)) MIDFUNC(1,fmov_0,(FW r)) { @@ -2487,55 +2346,48 @@ MIDFUNC(1,fmov_0,(FW r)) raw_fmov_0(r); f_unlock(r); } -MENDFUNC(1,fmov_0,(FW r)) -MIDFUNC(2,fmov_rm,(FW r, MEMR m)) +MIDFUNC(2,fmov_rm,(FW r, MEMPTRR m)) { r=f_writereg(r); raw_fmov_rm(r,m); f_unlock(r); } -MENDFUNC(2,fmov_rm,(FW r, MEMR m)) -MIDFUNC(2,fmovi_rm,(FW r, MEMR m)) +MIDFUNC(2,fmovi_rm,(FW r, MEMPTRR m)) { r=f_writereg(r); raw_fmovi_rm(r,m); f_unlock(r); } -MENDFUNC(2,fmovi_rm,(FW r, MEMR m)) -MIDFUNC(2,fmovi_mr,(MEMW m, FR r)) +MIDFUNC(2,fmovi_mr,(MEMPTRW m, FR r)) { r=f_readreg(r); raw_fmovi_mr(m,r); f_unlock(r); } -MENDFUNC(2,fmovi_mr,(MEMW m, FR r)) -MIDFUNC(3,fmovi_mrb,(MEMW m, FR r, double *bounds)) +MIDFUNC(3,fmovi_mrb,(MEMPTRW m, FR r, double *bounds)) { r=f_readreg(r); raw_fmovi_mrb(m,r,bounds); f_unlock(r); } -MENDFUNC(3,fmovi_mrb,(MEMW m, FR r, double *bounds)) -MIDFUNC(2,fmovs_rm,(FW r, MEMR m)) +MIDFUNC(2,fmovs_rm,(FW r, MEMPTRR m)) { r=f_writereg(r); raw_fmovs_rm(r,m); f_unlock(r); } -MENDFUNC(2,fmovs_rm,(FW r, MEMR m)) -MIDFUNC(2,fmovs_mr,(MEMW m, FR r)) +MIDFUNC(2,fmovs_mr,(MEMPTRW m, FR r)) { r=f_readreg(r); raw_fmovs_mr(m,r); f_unlock(r); } -MENDFUNC(2,fmovs_mr,(MEMW m, FR r)) MIDFUNC(1,fcuts_r,(FRW r)) { @@ -2543,7 +2395,6 @@ MIDFUNC(1,fcuts_r,(FRW r)) raw_fcuts_r(r); f_unlock(r); } -MENDFUNC(1,fcuts_r,(FRW r)) MIDFUNC(1,fcut_r,(FRW r)) { @@ -2551,31 +2402,27 @@ MIDFUNC(1,fcut_r,(FRW r)) raw_fcut_r(r); f_unlock(r); } -MENDFUNC(1,fcut_r,(FRW r)) -MIDFUNC(2,fmov_ext_mr,(MEMW m, FR r)) +MIDFUNC(2,fmov_ext_mr,(MEMPTRW m, FR r)) { r=f_readreg(r); raw_fmov_ext_mr(m,r); f_unlock(r); } -MENDFUNC(2,fmov_ext_mr,(MEMW m, FR r)) -MIDFUNC(2,fmov_mr,(MEMW m, FR r)) +MIDFUNC(2,fmov_mr,(MEMPTRW m, FR r)) { r=f_readreg(r); raw_fmov_mr(m,r); f_unlock(r); } -MENDFUNC(2,fmov_mr,(MEMW m, FR r)) -MIDFUNC(2,fmov_ext_rm,(FW r, MEMR m)) +MIDFUNC(2,fmov_ext_rm,(FW r, MEMPTRR m)) { r=f_writereg(r); raw_fmov_ext_rm(r,m); f_unlock(r); } -MENDFUNC(2,fmov_ext_rm,(FW r, MEMR m)) MIDFUNC(2,fmov_rr,(FW d, FR s)) { @@ -2599,7 +2446,6 @@ MIDFUNC(2,fmov_rr,(FW d, FR s)) f_unlock(d); #endif } -MENDFUNC(2,fmov_rr,(FW d, FR s)) MIDFUNC(2,fldcw_m_indexed,(RR4 index, IMM base)) { @@ -2608,7 +2454,6 @@ MIDFUNC(2,fldcw_m_indexed,(RR4 index, IMM base)) raw_fldcw_m_indexed(index,base); unlock2(index); } -MENDFUNC(2,fldcw_m_indexed,(RR4 index, IMM base)) MIDFUNC(1,ftst_r,(FR r)) { @@ -2616,13 +2461,11 @@ MIDFUNC(1,ftst_r,(FR r)) raw_ftst_r(r); f_unlock(r); } -MENDFUNC(1,ftst_r,(FR r)) MIDFUNC(0,dont_care_fflags,(void)) { f_disassociate(FP_RESULT); } -MENDFUNC(0,dont_care_fflags,(void)) MIDFUNC(2,fsqrt_rr,(FW d, FR s)) { @@ -2632,7 +2475,6 @@ MIDFUNC(2,fsqrt_rr,(FW d, FR s)) f_unlock(s); f_unlock(d); } -MENDFUNC(2,fsqrt_rr,(FW d, FR s)) MIDFUNC(2,fabs_rr,(FW d, FR s)) { @@ -2642,7 +2484,6 @@ MIDFUNC(2,fabs_rr,(FW d, FR s)) f_unlock(s); f_unlock(d); } -MENDFUNC(2,fabs_rr,(FW d, FR s)) MIDFUNC(2,fgetexp_rr,(FW d, FR s)) { @@ -2652,7 +2493,6 @@ MIDFUNC(2,fgetexp_rr,(FW d, FR s)) f_unlock(s); f_unlock(d); } -MENDFUNC(2,fgetexp_rr,(FW d, FR s)) MIDFUNC(2,fgetman_rr,(FW d, FR s)) { @@ -2662,7 +2502,6 @@ MIDFUNC(2,fgetman_rr,(FW d, FR s)) f_unlock(s); f_unlock(d); } -MENDFUNC(2,fgetman_rr,(FW d, FR s)) MIDFUNC(2,fsin_rr,(FW d, FR s)) { @@ -2672,7 +2511,6 @@ MIDFUNC(2,fsin_rr,(FW d, FR s)) f_unlock(s); f_unlock(d); } -MENDFUNC(2,fsin_rr,(FW d, FR s)) MIDFUNC(2,fcos_rr,(FW d, FR s)) { @@ -2682,7 +2520,6 @@ MIDFUNC(2,fcos_rr,(FW d, FR s)) f_unlock(s); f_unlock(d); } -MENDFUNC(2,fcos_rr,(FW d, FR s)) MIDFUNC(2,ftan_rr,(FW d, FR s)) { @@ -2692,7 +2529,6 @@ MIDFUNC(2,ftan_rr,(FW d, FR s)) f_unlock(s); f_unlock(d); } -MENDFUNC(2,ftan_rr,(FW d, FR s)) MIDFUNC(3,fsincos_rr,(FW d, FW c, FR s)) { @@ -2704,7 +2540,6 @@ MIDFUNC(3,fsincos_rr,(FW d, FW c, FR s)) f_unlock(d); f_unlock(c); } -MENDFUNC(3,fsincos_rr,(FW d, FW c, FR s)) MIDFUNC(2,fscale_rr,(FRW d, FR s)) { @@ -2714,7 +2549,6 @@ MIDFUNC(2,fscale_rr,(FRW d, FR s)) f_unlock(s); f_unlock(d); } -MENDFUNC(2,fscale_rr,(FRW d, FR s)) MIDFUNC(2,ftwotox_rr,(FW d, FR s)) { @@ -2724,7 +2558,6 @@ MIDFUNC(2,ftwotox_rr,(FW d, FR s)) f_unlock(s); f_unlock(d); } -MENDFUNC(2,ftwotox_rr,(FW d, FR s)) MIDFUNC(2,fetox_rr,(FW d, FR s)) { @@ -2734,7 +2567,6 @@ MIDFUNC(2,fetox_rr,(FW d, FR s)) f_unlock(s); f_unlock(d); } -MENDFUNC(2,fetox_rr,(FW d, FR s)) MIDFUNC(2,frndint_rr,(FW d, FR s)) { @@ -2744,7 +2576,6 @@ MIDFUNC(2,frndint_rr,(FW d, FR s)) f_unlock(s); f_unlock(d); } -MENDFUNC(2,frndint_rr,(FW d, FR s)) MIDFUNC(2,fetoxM1_rr,(FW d, FR s)) { @@ -2754,7 +2585,6 @@ MIDFUNC(2,fetoxM1_rr,(FW d, FR s)) f_unlock(s); f_unlock(d); } -MENDFUNC(2,fetoxM1_rr,(FW d, FR s)) MIDFUNC(2,ftentox_rr,(FW d, FR s)) { @@ -2764,7 +2594,6 @@ MIDFUNC(2,ftentox_rr,(FW d, FR s)) f_unlock(s); f_unlock(d); } -MENDFUNC(2,ftentox_rr,(FW d, FR s)) MIDFUNC(2,flog2_rr,(FW d, FR s)) { @@ -2774,7 +2603,6 @@ MIDFUNC(2,flog2_rr,(FW d, FR s)) f_unlock(s); f_unlock(d); } -MENDFUNC(2,flog2_rr,(FW d, FR s)) MIDFUNC(2,flogN_rr,(FW d, FR s)) { @@ -2784,7 +2612,6 @@ MIDFUNC(2,flogN_rr,(FW d, FR s)) f_unlock(s); f_unlock(d); } -MENDFUNC(2,flogN_rr,(FW d, FR s)) MIDFUNC(2,flogNP1_rr,(FW d, FR s)) { @@ -2794,7 +2621,6 @@ MIDFUNC(2,flogNP1_rr,(FW d, FR s)) f_unlock(s); f_unlock(d); } -MENDFUNC(2,flogNP1_rr,(FW d, FR s)) MIDFUNC(2,flog10_rr,(FW d, FR s)) { @@ -2804,7 +2630,6 @@ MIDFUNC(2,flog10_rr,(FW d, FR s)) f_unlock(s); f_unlock(d); } -MENDFUNC(2,flog10_rr,(FW d, FR s)) MIDFUNC(2,fasin_rr,(FW d, FR s)) { @@ -2814,7 +2639,6 @@ MIDFUNC(2,fasin_rr,(FW d, FR s)) f_unlock(s); f_unlock(d); } -MENDFUNC(2,fasin_rr,(FW d, FR s)) MIDFUNC(2,facos_rr,(FW d, FR s)) { @@ -2824,7 +2648,6 @@ MIDFUNC(2,facos_rr,(FW d, FR s)) f_unlock(s); f_unlock(d); } -MENDFUNC(2,facos_rr,(FW d, FR s)) MIDFUNC(2,fatan_rr,(FW d, FR s)) { @@ -2834,7 +2657,6 @@ MIDFUNC(2,fatan_rr,(FW d, FR s)) f_unlock(s); f_unlock(d); } -MENDFUNC(2,fatan_rr,(FW d, FR s)) MIDFUNC(2,fatanh_rr,(FW d, FR s)) { @@ -2844,7 +2666,6 @@ MIDFUNC(2,fatanh_rr,(FW d, FR s)) f_unlock(s); f_unlock(d); } -MENDFUNC(2,fatanh_rr,(FW d, FR s)) MIDFUNC(2,fsinh_rr,(FW d, FR s)) { @@ -2854,7 +2675,6 @@ MIDFUNC(2,fsinh_rr,(FW d, FR s)) f_unlock(s); f_unlock(d); } -MENDFUNC(2,fsinh_rr,(FW d, FR s)) MIDFUNC(2,fcosh_rr,(FW d, FR s)) { @@ -2864,7 +2684,6 @@ MIDFUNC(2,fcosh_rr,(FW d, FR s)) f_unlock(s); f_unlock(d); } -MENDFUNC(2,fcosh_rr,(FW d, FR s)) MIDFUNC(2,ftanh_rr,(FW d, FR s)) { @@ -2874,7 +2693,6 @@ MIDFUNC(2,ftanh_rr,(FW d, FR s)) f_unlock(s); f_unlock(d); } -MENDFUNC(2,ftanh_rr,(FW d, FR s)) MIDFUNC(2,fneg_rr,(FW d, FR s)) { @@ -2884,7 +2702,6 @@ MIDFUNC(2,fneg_rr,(FW d, FR s)) f_unlock(s); f_unlock(d); } -MENDFUNC(2,fneg_rr,(FW d, FR s)) MIDFUNC(2,fadd_rr,(FRW d, FR s)) { @@ -2894,7 +2711,6 @@ MIDFUNC(2,fadd_rr,(FRW d, FR s)) f_unlock(s); f_unlock(d); } -MENDFUNC(2,fadd_rr,(FRW d, FR s)) MIDFUNC(2,fsub_rr,(FRW d, FR s)) { @@ -2904,7 +2720,6 @@ MIDFUNC(2,fsub_rr,(FRW d, FR s)) f_unlock(s); f_unlock(d); } -MENDFUNC(2,fsub_rr,(FRW d, FR s)) MIDFUNC(2,fcmp_rr,(FR d, FR s)) { @@ -2914,7 +2729,6 @@ MIDFUNC(2,fcmp_rr,(FR d, FR s)) f_unlock(s); f_unlock(d); } -MENDFUNC(2,fcmp_rr,(FR d, FR s)) MIDFUNC(2,fdiv_rr,(FRW d, FR s)) { @@ -2924,7 +2738,6 @@ MIDFUNC(2,fdiv_rr,(FRW d, FR s)) f_unlock(s); f_unlock(d); } -MENDFUNC(2,fdiv_rr,(FRW d, FR s)) MIDFUNC(2,frem_rr,(FRW d, FR s)) { @@ -2934,7 +2747,6 @@ MIDFUNC(2,frem_rr,(FRW d, FR s)) f_unlock(s); f_unlock(d); } -MENDFUNC(2,frem_rr,(FRW d, FR s)) MIDFUNC(2,frem1_rr,(FRW d, FR s)) { @@ -2944,7 +2756,6 @@ MIDFUNC(2,frem1_rr,(FRW d, FR s)) f_unlock(s); f_unlock(d); } -MENDFUNC(2,frem1_rr,(FRW d, FR s)) MIDFUNC(2,fmul_rr,(FRW d, FR s)) { @@ -2954,7 +2765,6 @@ MIDFUNC(2,fmul_rr,(FRW d, FR s)) f_unlock(s); f_unlock(d); } -MENDFUNC(2,fmul_rr,(FRW d, FR s)) #ifdef __GNUC__ @@ -3008,3 +2818,9 @@ static inline void write_jmp_target(uae_u32 *jmpaddr, cpuop_func* a) { static inline void emit_jmp_target(uae_u32 a) { emit_long(a-((uintptr)target+4)); } + + +void compemu_bkpt(void) +{ + emit_byte(0xcc); +} diff --git a/jit/compemu_midfunc_x86.h b/jit/compemu_midfunc_x86.h index a477f6ed..82b75415 100644 --- a/jit/compemu_midfunc_x86.h +++ b/jit/compemu_midfunc_x86.h @@ -141,13 +141,14 @@ DECLARE_MIDFUNC(mov_b_rm(W1 d, IMM s)); DECLARE_MIDFUNC(mov_l_ri(W4 d, IMM s)); DECLARE_MIDFUNC(mov_w_ri(W2 d, IMM s)); DECLARE_MIDFUNC(mov_b_ri(W1 d, IMM s)); -DECLARE_MIDFUNC(add_l_mi(IMM d, IMM s) ); -DECLARE_MIDFUNC(add_w_mi(IMM d, IMM s) ); -DECLARE_MIDFUNC(add_b_mi(IMM d, IMM s) ); +DECLARE_MIDFUNC(add_l_mi(IMM d, IMM s)); +DECLARE_MIDFUNC(add_w_mi(IMM d, IMM s)); +DECLARE_MIDFUNC(add_b_mi(IMM d, IMM s)); DECLARE_MIDFUNC(test_l_ri(RR4 d, IMM i)); DECLARE_MIDFUNC(test_l_rr(RR4 d, RR4 s)); DECLARE_MIDFUNC(test_w_rr(RR2 d, RR2 s)); DECLARE_MIDFUNC(test_b_rr(RR1 d, RR1 s)); +DECLARE_MIDFUNC(test_b_mi(IMM d, IMM s)); DECLARE_MIDFUNC(and_l_ri(RW4 d, IMM i)); DECLARE_MIDFUNC(and_l(RW4 d, RR4 s)); DECLARE_MIDFUNC(and_w(RW2 d, RR2 s)); @@ -185,7 +186,7 @@ DECLARE_MIDFUNC(xor_b(RW1 d, RR1 s)); DECLARE_MIDFUNC(live_flags(void)); DECLARE_MIDFUNC(dont_care_flags(void)); DECLARE_MIDFUNC(duplicate_carry(void)); -DECLARE_MIDFUNC(setcc_for_cntzero(RR4 d)); +DECLARE_MIDFUNC(setcc_for_cntzero(RR4 d, RR4 data, int size)); DECLARE_MIDFUNC(restore_carry(void)); DECLARE_MIDFUNC(start_needflags(void)); DECLARE_MIDFUNC(end_needflags(void)); @@ -202,17 +203,17 @@ DECLARE_MIDFUNC(fmov_log2_e(FW r)); DECLARE_MIDFUNC(fmov_loge_2(FW r)); DECLARE_MIDFUNC(fmov_1(FW r)); DECLARE_MIDFUNC(fmov_0(FW r)); -DECLARE_MIDFUNC(fmov_rm(FW r, MEMR m)); -DECLARE_MIDFUNC(fmov_mr(MEMW m, FR r)); -DECLARE_MIDFUNC(fmovi_rm(FW r, MEMR m)); -DECLARE_MIDFUNC(fmovi_mr(MEMW m, FR r)); -DECLARE_MIDFUNC(fmovi_mrb(MEMW m, FR r, double *bounds)); -DECLARE_MIDFUNC(fmovs_rm(FW r, MEMR m)); -DECLARE_MIDFUNC(fmovs_mr(MEMW m, FR r)); +DECLARE_MIDFUNC(fmov_rm(FW r, MEMPTRR m)); +DECLARE_MIDFUNC(fmov_mr(MEMPTRW m, FR r)); +DECLARE_MIDFUNC(fmovi_rm(FW r, MEMPTRR m)); +DECLARE_MIDFUNC(fmovi_mr(MEMPTRW m, FR r)); +DECLARE_MIDFUNC(fmovi_mrb(MEMPTRW m, FR r, double *bounds)); +DECLARE_MIDFUNC(fmovs_rm(FW r, MEMPTRR m)); +DECLARE_MIDFUNC(fmovs_mr(MEMPTRW m, FR r)); DECLARE_MIDFUNC(fcuts_r(FRW r)); DECLARE_MIDFUNC(fcut_r(FRW r)); -DECLARE_MIDFUNC(fmov_ext_mr(MEMW m, FR r)); -DECLARE_MIDFUNC(fmov_ext_rm(FW r, MEMR m)); +DECLARE_MIDFUNC(fmov_ext_mr(MEMPTRW m, FR r)); +DECLARE_MIDFUNC(fmov_ext_rm(FW r, MEMPTRR m)); DECLARE_MIDFUNC(fmov_rr(FW d, FR s)); DECLARE_MIDFUNC(fldcw_m_indexed(RR4 index, IMM base)); DECLARE_MIDFUNC(ftst_r(FR r)); diff --git a/jit/compemu_support.cpp b/jit/compemu_support.cpp index fc1eec21..96412351 100644 --- a/jit/compemu_support.cpp +++ b/jit/compemu_support.cpp @@ -64,9 +64,10 @@ #ifdef JIT #ifdef UAE +#define bug write_log #include "options.h" #include "events.h" -#include "memory.h" +#include "uae/memory.h" #include "custom.h" #else #include "cpu_emulation.h" @@ -81,16 +82,30 @@ #include "comptbl.h" #ifdef UAE #include "compemu.h" +#ifdef FSUAE +#include "codegen_udis86.h" +#endif #else #include "compiler/compemu.h" #include "fpu/fpu.h" #include "fpu/flags.h" #include "parameters.h" +static void build_comp(void); +#endif +#ifndef UAE +#include "verify.h" #endif #ifdef UAE +#ifdef FSUAE +#include "uae/fs.h" +#endif #include "uae/log.h" +#if defined(__pie__) || defined (__PIE__) +#error Position-independent code (PIE) cannot be used with JIT +#endif + #include "uae/vm.h" #define VM_PAGE_READ UAE_VM_READ #define VM_PAGE_WRITE UAE_VM_WRITE @@ -120,8 +135,6 @@ static inline void *vm_acquire(size_t size, int options = VM_MAP_DEFAULT) #define FIXED_ADDRESSING 1 #endif -#define SAHF_SETO_PROFITABLE - // %%% BRIAN KING WAS HERE %%% extern bool canbang; @@ -136,6 +149,15 @@ static inline int distrust_check(int value) return 1; #else int distrust = value; +#ifdef FSUAE + switch (value) { + case 0: distrust = 0; break; + case 1: distrust = 1; break; + case 2: distrust = ((start_pc & 0xF80000) == 0xF80000); break; + case 3: distrust = !have_done_picasso; break; + default: abort(); + } +#endif return distrust; #endif } @@ -205,7 +227,7 @@ void jit_abort(const char *format, ...) #ifdef RECORD_REGISTER_USAGE static uint64 reg_count[16]; -static int reg_count_local[16]; +static uint64 reg_count_local[16]; static int reg_count_compare(const void *ap, const void *bp) { @@ -246,15 +268,13 @@ uae_u8* comp_pc_p; /* defined in uae.h */ #else // External variables -// newcpu.cpp -extern int quit_program; #endif // gb-- Extra data for Basilisk II/JIT #ifdef JIT_DEBUG -static bool JITDebug = false; // Enable runtime disassemblers through mon? +#define JITDebug bx_options.jit.jitdebug // Enable runtime disassemblers through mon? #else -const bool JITDebug = false; // Don't use JIT debug mode at all +#define JITDebug false // Don't use JIT debug mode at all #endif #if USE_INLINING #ifdef UAE @@ -266,10 +286,10 @@ static bool follow_const_jumps = true; // Flag: translation through constant jum const bool follow_const_jumps = false; #endif -const uae_u32 MIN_CACHE_SIZE = 1024; // Minimal translation cache size (1 MB) static uae_u32 cache_size = 0; // Size of total cache allocated for compiled blocks static uae_u32 current_cache_size = 0; // Cache grows upwards: how much has been consumed already static bool lazy_flush = true; // Flag: lazy translation cache invalidation +// Flag: compile FPU instructions ? #ifdef UAE #ifdef USE_JIT_FPU #define avoid_fpu (!currprefs.compfpu) @@ -277,7 +297,11 @@ static bool lazy_flush = true; // Flag: lazy translation cache invalidation #define avoid_fpu (true) #endif #else -static bool avoid_fpu = true; // Flag: compile FPU instructions ? +#ifdef USE_JIT_FPU +#define avoid_fpu (!bx_options.jit.jitfpu) +#else +#define avoid_fpu (true) +#endif #endif static bool have_cmov = false; // target has CMOV instructions ? static bool have_rat_stall = true; // target has partial register stalls ? @@ -298,27 +322,15 @@ static int optcount[10] = { }; #ifdef UAE -/* FIXME: op_properties is currently in compemu.h */ - op_properties prop[65536]; - -static inline bool is_const_jump(uae_u32 opcode) -{ - return prop[opcode].is_const_jump != 0; -} #else -struct op_properties { - uae_u8 use_flags; - uae_u8 set_flags; - uae_u8 is_addx; - uae_u8 cflow; -}; static op_properties prop[65536]; static inline int end_block(uae_u32 opcode) { return (prop[opcode].cflow & fl_end_block); } +#endif static inline bool is_const_jump(uae_u32 opcode) { @@ -332,12 +344,14 @@ static inline bool may_trap(uae_u32 opcode) } #endif -#endif - static inline unsigned int cft_map (unsigned int f) { #ifdef UAE +#if !defined(HAVE_GET_WORD_UNSWAPPED) return f; +#else + return do_byteswap_16(f); +#endif #else #if !defined(HAVE_GET_WORD_UNSWAPPED) || defined(FULLMMU) return f; @@ -357,6 +371,9 @@ static uintptr taken_pc_p; static int branch_cc; static int redo_current_block; +#ifdef UAE +int segvcount=0; +#endif static uae_u8* current_compile_p=NULL; static uae_u8* max_compile_start; static uae_u8* compiled_code=NULL; @@ -385,30 +402,28 @@ static blockinfo* dormant; #ifdef NOFLAGS_SUPPORT /* 68040 */ -extern const struct cputbl op_smalltbl_0_nf[]; +extern const struct cputbl op_smalltbl_0[]; #endif extern const struct comptbl op_smalltbl_0_comp_nf[]; extern const struct comptbl op_smalltbl_0_comp_ff[]; #ifdef NOFLAGS_SUPPORT /* 68020 + 68881 */ -extern const struct cputbl op_smalltbl_1_nf[]; +extern const struct cputbl op_smalltbl_1[]; /* 68020 */ -extern const struct cputbl op_smalltbl_2_nf[]; +extern const struct cputbl op_smalltbl_2[]; /* 68010 */ -extern const struct cputbl op_smalltbl_3_nf[]; +extern const struct cputbl op_smalltbl_3[]; /* 68000 */ -extern const struct cputbl op_smalltbl_4_nf[]; +extern const struct cputbl op_smalltbl_4[]; /* 68000 slow but compatible. */ -extern const struct cputbl op_smalltbl_5_nf[]; +extern const struct cputbl op_smalltbl_5[]; #endif -#ifdef WINUAE_ARANYM -static void flush_icache_hard(int n); -static void flush_icache_lazy(int n); -static void flush_icache_none(int n); -void (*flush_icache)(int n) = flush_icache_none; -#endif +static void flush_icache_hard(int); +static void flush_icache_lazy(int); +static void flush_icache_none(int); +//void (*flush_icache)(int) = flush_icache_none; static bigstate live; static smallstate empty_ss; @@ -420,13 +435,8 @@ static void unlock2(int r); static void setlock(int r); static int readreg_specific(int r, int size, int spec); static int writereg_specific(int r, int size, int spec); -static void prepare_for_call_1(void); -static void prepare_for_call_2(void); -static void align_target(uae_u32 a); -static void inline flush_cpu_icache(void *from, void *to); static void inline write_jmp_target(uae_u32 *jmpaddr, cpuop_func* a); -static void inline emit_jmp_target(uae_u32 a); uae_u32 m68k_pc_offset; @@ -503,7 +513,9 @@ static inline blockinfo* get_blockinfo_addr(void* addr) #endif #include "disasm-glue.h" -#ifdef JIT_DEBUG +bool disasm_this_inst; + +#if defined(JIT_DEBUG) || (defined(HAVE_DISASM_NATIVE) && defined(HAVE_DISASM_M68K)) static void disasm_block(int disasm_target, const uint8 *start, size_t length) { UNUSED(start); @@ -518,7 +530,7 @@ static void disasm_block(int disasm_target, const uint8 *start, size_t length) disasm_info.memory_vma = ((memptr)((uintptr_t)(start) - MEMBaseDiff)); while (length > 0) { - int isize = m68k_disasm_to_buf(&disasm_info, buf); + int isize = m68k_disasm_to_buf(&disasm_info, buf, 1); bug("%s", buf); if (isize < 0) break; @@ -538,7 +550,7 @@ static void disasm_block(int disasm_target, const uint8 *start, size_t length) while (start < end) { - start = x86_disasm(start, buf); + start = x86_disasm(start, buf, 1); bug("%s", buf); } } @@ -552,7 +564,7 @@ static void disasm_block(int disasm_target, const uint8 *start, size_t length) while (start < end) { - start = arm_disasm(start, buf); + start = arm_disasm(start, buf, 1); bug("%s", buf); } } @@ -571,7 +583,7 @@ static inline void disasm_m68k_block(const uint8 *start, size_t length) disasm_block(TARGET_M68K, start, length); } #endif -#endif +#endif /* WINUAE_ARANYM */ /******************************************************************* @@ -808,7 +820,7 @@ static inline blockinfo* get_blockinfo_addr_new(void* addr, int /* setstate */) static void prepare_block(blockinfo* bi); -/* Management of blockinfos. +/* Managment of blockinfos. A blockinfo struct is allocated whenever a new block has to be compiled. If the list of free blockinfos is empty, we allocate a new @@ -1029,14 +1041,7 @@ static inline void emit_block(const uae_u8 *block, uae_u32 blocklen) static inline uae_u32 reverse32(uae_u32 v) { -#ifdef WINUAE_ARANYM - // gb-- We have specialized byteswapping functions, just use them return do_byteswap_32(v); -#elif _MSC_VER - return _byteswap_ulong(v); -#else - return ((v>>24)&0xff) | ((v>>8)&0xff00) | ((v<<8)&0xff0000) | ((v<<24)&0xff000000); -#endif } void set_target(uae_u8* t) @@ -1519,9 +1524,9 @@ static inline void log_visused(int r) static inline void do_load_reg(int n, int r) { if (r == FLAGTMP) - raw_load_flagreg(n, r); + raw_load_flagreg(n); else if (r == FLAGX) - raw_load_flagx(n, r); + raw_load_flagx(n); else compemu_raw_mov_l_rm(n, (uintptr) live.state[r].mem); } @@ -1742,6 +1747,7 @@ static inline void disassociate(int r) evict(r); } +/* XXFIXME: val may be 64bit address for PC_P */ static inline void set_const(int r, uae_u32 val) { disassociate(r); @@ -2310,11 +2316,11 @@ static void bt_l_ri_noclobber(RR4 r, IMM i) static void f_tomem(int r) { if (live.fate[r].status==DIRTY) { - if (use_long_double) { - raw_fmov_ext_mr((uintptr)live.fate[r].mem, live.fate[r].realreg); - } else { - raw_fmov_mr((uintptr)live.fate[r].mem, live.fate[r].realreg); - } +#if defined(USE_LONG_DOUBLE) + raw_fmov_ext_mr((uintptr)live.fate[r].mem,live.fate[r].realreg); +#else + raw_fmov_mr((uintptr)live.fate[r].mem,live.fate[r].realreg); +#endif live.fate[r].status=CLEAN; } } @@ -2322,11 +2328,11 @@ static void f_tomem(int r) static void f_tomem_drop(int r) { if (live.fate[r].status==DIRTY) { - if (use_long_double) { - raw_fmov_ext_mr_drop((uintptr)live.fate[r].mem, live.fate[r].realreg); - } else { - raw_fmov_mr_drop((uintptr)live.fate[r].mem, live.fate[r].realreg); - } +#if defined(USE_LONG_DOUBLE) + raw_fmov_ext_mr_drop((uintptr)live.fate[r].mem,live.fate[r].realreg); +#else + raw_fmov_mr_drop((uintptr)live.fate[r].mem,live.fate[r].realreg); +#endif live.fate[r].status=INMEM; } } @@ -2430,11 +2436,11 @@ static int f_alloc_reg(int r, int willclobber) if (!willclobber) { if (live.fate[r].status!=UNDEF) { - if (use_long_double) { - raw_fmov_ext_rm(bestreg, (uintptr)live.fate[r].mem); - } else { - raw_fmov_rm(bestreg, (uintptr)live.fate[r].mem); - } +#if defined(USE_LONG_DOUBLE) + raw_fmov_ext_rm(bestreg,(uintptr)live.fate[r].mem); +#else + raw_fmov_rm(bestreg,(uintptr)live.fate[r].mem); +#endif } live.fate[r].status=CLEAN; } @@ -2558,6 +2564,80 @@ static inline int f_writereg(int r) return answer; } +/******************************************************************** + * Support functions, internal * + ********************************************************************/ + + +static void align_target(uae_u32 a) +{ + if (!a) + return; + + if (tune_nop_fillers) + raw_emit_nop_filler(a - (((uintptr)target) & (a - 1))); + else { + /* Fill with NOPs --- makes debugging with gdb easier */ + while ((uintptr)target&(a-1)) + emit_byte(0x90); // Attention x86 specific code + } +} + +static inline int isinrom(uintptr addr) +{ +#ifdef UAE + return (addr >= uae_p32(kickmem_bank.baseaddr) && + addr < uae_p32(kickmem_bank.baseaddr + 8 * 65536)); +#else + return ((addr >= (uintptr)ROMBaseHost) && (addr < (uintptr)ROMBaseHost + ROMSize)); +#endif +} + +#if defined(UAE) || defined(FLIGHT_RECORDER) +static void flush_all(void) +{ + int i; + + log_flush(); + for (i=0;i0) + free_nreg(i); + + for (i=0;i0) + f_free_nreg(i); + + live.flags_in_flags=TRASH; /* Note: We assume we already rescued the + flags at the very start of the call_r + functions! */ +} +#endif + #if defined(CPU_arm) #include "compemu_midfunc_arm.cpp" @@ -2610,6 +2690,165 @@ void sync_m68k_pc(void) } } +/* for building exception frames */ +void compemu_exc_make_frame(int format, int sr, int ret, int nr, int tmp) +{ + lea_l_brr(SP_REG, SP_REG, -2); + mov_l_ri(tmp, (format << 12) + (nr * 4)); /* format | vector */ + writeword(SP_REG, tmp, tmp); + + lea_l_brr(SP_REG, SP_REG, -4); + writelong(SP_REG, ret, tmp); + + lea_l_brr(SP_REG, SP_REG, -2); + writeword_clobber(SP_REG, sr, tmp); + remove_offset(SP_REG, -1); + if (isinreg(SP_REG)) + evict(SP_REG); + else + flush_reg(SP_REG); +} + +void compemu_make_sr(int sr, int tmp) +{ + flush_flags(); /* low level */ + flush_reg(FLAGX); + +#if defined (OPTIMIZED_FLAGS) || defined(UAE) + + /* + * x86 EFLAGS: (!SAHF_SETO_PROFITABLE) + * FEDCBA98 76543210 + * ----V--- NZ-----C + * + * <--AH--> <--AL--> (SAHF_SETO_PROFITABLE) + * FEDCBA98 76543210 + * NZxxxxxC xxxxxxxV + * + * arm RFLAGS: + * FEDCBA98 76543210 FEDCBA98 76543210 + * NZCV---- -------- -------- -------- + * + * -> m68k SR: + * --S--III ---XNZVC + * + * Master-Bit and traceflags are ignored here, + * since they are not emulated in JIT code + */ + mov_l_rm(sr, uae_p32(live.state[FLAGTMP].mem)); + mov_l_ri(tmp, FLAGVAL_N|FLAGVAL_Z|FLAGVAL_V|FLAGVAL_C); + and_l(sr, tmp); + mov_l_rr(tmp, sr); + +#if (defined(CPU_i386) && defined(X86_ASSEMBLY)) || (defined(CPU_x86_64) && defined(X86_64_ASSEMBLY)) +#ifndef SAHF_SETO_PROFITABLE + ror_b_ri(sr, FLAGBIT_N - 3); /* move NZ into position; C->4 */ + shrl_w_ri(tmp, FLAGBIT_V - 1); /* move V into position in tmp */ + or_l(sr, tmp); /* or V flag to SR */ + mov_l_rr(tmp, sr); + shrl_b_ri(tmp, (8 - (FLAGBIT_N - 3)) - FLAGBIT_C); /* move C into position in tmp */ + or_l(sr, tmp); /* or C flag to SR */ +#else + ror_w_ri(sr, FLAGBIT_N - 3); /* move NZ in position; V->4, C->12 */ + shrl_w_ri(tmp, (16 - (FLAGBIT_N - 3)) - FLAGBIT_V - 1); /* move V into position in tmp; C->9 */ + or_l(sr, tmp); /* or V flag to SR */ + shrl_w_ri(tmp, FLAGBIT_C + FLAGBIT_V - 1); /* move C into position in tmp */ + or_l(sr, tmp); /* or C flag to SR */ +#endif + mov_l_ri(tmp, 0x0f); + and_l(sr, tmp); + + mov_b_rm(tmp, uae_p32(®flags.x)); + and_l_ri(tmp, FLAGVAL_X); + shll_l_ri(tmp, 4); + or_l(sr, tmp); + +#elif defined(CPU_arm) && defined(ARM_ASSEMBLY) + shrl_l_ri(sr, FLAGBIT_N - 3); /* move NZ into position */ + ror_l_ri(tmp, FLAGBIT_C - 1); /* move C into position in tmp; V->31 */ + and_l_ri(sr, 0xc); + or_l(sr, tmp); /* or C flag to SR */ + shrl_l_ri(tmp, 31); /* move V into position in tmp */ + or_l(sr, tmp); /* or V flag to SR */ + + mov_b_rm(tmp, uae_p32(®flags.x)); + and_l_ri(tmp, FLAGVAL_X); + shrl_l_ri(tmp, FLAGBIT_X - 4); + or_l(sr, tmp); + +#else +#error "unknown CPU" +#endif + +#else + + xor_l(sr, sr); + xor_l(tmp, tmp); + mov_b_rm(tmp, uae_p32(®s.c)); + shll_l_ri(tmp, 0); + or_l(sr, tmp); + mov_b_rm(tmp, uae_p32(®s.v)); + shll_l_ri(tmp, 1); + or_l(sr, tmp); + mov_b_rm(tmp, uae_p32(®s.z)); + shll_l_ri(tmp, 2); + or_l(sr, tmp); + mov_b_rm(tmp, uae_p32(®s.n)); + shll_l_ri(tmp, 3); + or_l(sr, tmp); + +#endif /* OPTIMIZED_FLAGS */ + + mov_b_rm(tmp, uae_p32(®s.s)); + shll_l_ri(tmp, 13); + or_l(sr, tmp); + mov_l_rm(tmp, uae_p32(®s.intmask)); + shll_l_ri(tmp, 8); + or_l(sr, tmp); + and_l_ri(sr, 0x271f); + mov_w_mr(uae_p32(®s.sr), sr); +} + +void compemu_enter_super(int sr) +{ +#if 0 + fprintf(stderr, "enter_super: isinreg=%d rr=%d nholds=%d\n", isinreg(SP_REG), live.state[SP_REG].realreg, isinreg(SP_REG) ? live.nat[live.state[SP_REG].realreg].nholds : -1); +#endif + remove_offset(SP_REG, -1); + if (isinreg(SP_REG)) + evict(SP_REG); + else + flush_reg(SP_REG); + /* + * equivalent to: + * if (!regs.s) + * { + * regs.usp = m68k_areg(regs, 7); + * m68k_areg(regs, 7) = regs.isp; + * regs.s = 1; + * mmu_set_super(1); + * } + */ + test_l_ri(sr, 0x2000); +#if defined(CPU_i386) || defined(CPU_x86_64) + compemu_raw_jnz_b_oponly(); + uae_u8 *branchadd = get_target(); + skip_byte(); +#elif defined(CPU_arm) + compemu_raw_jnz_b_oponly(); + uae_u8 *branchadd = get_target(); + skip_byte(); +#endif + mov_l_mr((uintptr)®s.usp, SP_REG); + mov_l_rm(SP_REG, uae_p32(®s.isp)); + mov_b_mi(uae_p32(®s.s), 1); +#if defined(CPU_i386) || defined(CPU_x86_64) + *branchadd = get_target() - (branchadd + 1); +#elif defined(CPU_arm) + *((uae_u32 *)branchadd - 3) = get_target() - (branchadd + 1); +#endif +} + /******************************************************************** * Scratch registers management * ********************************************************************/ @@ -2630,30 +2869,19 @@ static inline const char *str_on_off(bool b) return b ? "on" : "off"; } -#ifdef UAE -static -#endif void compiler_init(void) { static bool initialized = false; if (initialized) return; + flush_icache = flush_icache_none; + #ifdef UAE + flush_icache = lazy_flush ? flush_icache_lazy : flush_icache_hard; #else -#ifdef JIT_DEBUG - // JIT debug mode ? - JITDebug = bx_options.jit.jitdebug; -#endif jit_log(" : enable runtime disassemblers : %s", JITDebug ? "yes" : "no"); -#ifdef USE_JIT_FPU - // Use JIT compiler for FPU instructions ? - avoid_fpu = !bx_options.jit.jitfpu; -#else - // JIT FPU is always disabled - avoid_fpu = true; -#endif jit_log(" : compile FPU instructions : %s", !avoid_fpu ? "yes" : "no"); // Get size of the translation cache (in KB) @@ -2685,6 +2913,7 @@ void compiler_init(void) jit_log(" : separate blockinfo allocation : %s", str_on_off(USE_SEPARATE_BIA)); // Build compiler tables + init_table68k(); build_comp(); #endif @@ -2700,9 +2929,6 @@ void compiler_init(void) #endif } -#ifdef UAE -static -#endif void compiler_exit(void) { #ifdef PROFILE_COMPILE_TIME @@ -2713,7 +2939,7 @@ void compiler_exit(void) #else #if DEBUG #if defined(USE_DATA_BUFFER) - jit_log("data_wasted = %d bytes", data_wasted); + jit_log("data_wasted = %ld bytes", data_wasted); #endif #endif @@ -2778,27 +3004,11 @@ void compiler_exit(void) 100.0*double(cum_reg_count)/double(tot_reg_count)); } #endif -} -#ifdef UAE -#else -bool compiler_use_jit(void) -{ - // Check for the "jit" prefs item - if (!bx_options.jit.jit) - return false; - - // Don't use JIT if translation cache size is less then MIN_CACHE_SIZE KB - if (bx_options.jit.jitcachesize < MIN_CACHE_SIZE) { - panicbug(" : translation cache size is less than %d KB. Disabling JIT.\n", MIN_CACHE_SIZE); - return false; - } - - return true; + exit_table68k(); } -#endif -void init_comp(void) +static void init_comp(void) { int i; uae_s8* cb=can_byte; @@ -2863,7 +3073,7 @@ void init_comp(void) } else if (i==FP_RESULT) { #ifdef UAE - live.fate[i].mem=(uae_u32*)(®s.fp_result.fp); + live.fate[i].mem=(uae_u32*)(®s.fp_result); #else live.fate[i].mem=(uae_u32*)(&fpu.result); #endif @@ -2905,6 +3115,39 @@ void init_comp(void) raw_fp_init(); } +void flush_reg(int reg) +{ + if (live.state[reg].needflush==NF_TOMEM) + { + switch (live.state[reg].status) + { + case INMEM: + if (live.state[reg].val) + { + compemu_raw_add_l_mi((uintptr)live.state[reg].mem, live.state[reg].val); + log_vwrite(reg); + live.state[reg].val = 0; + } + break; + case CLEAN: + case DIRTY: + remove_offset(reg, -1); + tomem(reg); + break; + case ISCONST: + if (reg != PC_P) + writeback_const(reg); + break; + default: + break; + } + Dif (live.state[reg].val && reg!=PC_P) + { + jit_log("Register %d still has val %x", reg, live.state[reg].val); + } + } +} + /* Only do this if you really mean it! The next call should be to init!*/ void flush(int save_regs) { @@ -2922,30 +3165,7 @@ void flush(int save_regs) } } for (i=0;i= uae_p32(kickmem_bank.baseaddr) && - addr < uae_p32(kickmem_bank.baseaddr + 8 * 65536)); -#else - return ((addr >= (uintptr)ROMBaseHost) && (addr < (uintptr)ROMBaseHost + ROMSize)); -#endif -} - -static void flush_all(void) -{ - int i; - - log_flush(); - for (i=0;i0) - free_nreg(i); - - for (i=0;i0) - f_free_nreg(i); - - live.flags_in_flags=TRASH; /* Note: We assume we already rescued the - flags at the very start of the call_r - functions! */ -} - /******************************************************************** * Memory access and related functions, CREATE time * ********************************************************************/ @@ -3355,7 +3503,7 @@ void get_n_addr(int address, int dest, int tmp) #if FIXED_ADDRESSING lea_l_brr(dest,address,MEMBaseDiff); #else -# error "Only fixed addressing mode supported" +# error "Only fixed adressing mode supported" #endif forget_about(tmp); (void) f; @@ -3469,7 +3617,7 @@ void calc_disp_ea_020(int base, uae_u32 dp, int target, int tmp) void set_cache_state(int enabled) { if (enabled!=cache_enabled) - flush_icache_hard(77); + flush_icache_hard(3); cache_enabled=enabled; } @@ -3503,7 +3651,7 @@ static inline uint8 *alloc_code(uint32 size) void alloc_cache(void) { if (compiled_code) { - flush_icache_hard(6); + flush_icache_hard(3); vm_release(compiled_code, cache_size * 1024); compiled_code = 0; } @@ -3825,6 +3973,9 @@ static inline void create_popalls(void) r=REG_PC_TMP; compemu_raw_mov_l_rm(r, uae_p32(®s.pc_p)); compemu_raw_and_l_ri(r,TAGMASK); + { + //verify(sizeof(cache_tags[0]) == sizeof(void *)); + } compemu_raw_jmp_m_indexed(uae_p32(cache_tags), r, sizeof(void *)); /* now the exit points */ @@ -3959,12 +4110,98 @@ static int read_opcode(const char *p) return opcode; } + +#ifdef USE_JIT_FPU +static struct { + const char *name; + bool *const disabled; +} const jit_opcodes[] = { + { "fbcc", &jit_disable.fbcc }, + { "fdbcc", &jit_disable.fdbcc }, + { "fscc", &jit_disable.fscc }, + { "ftrapcc", &jit_disable.ftrapcc }, + { "fsave", &jit_disable.fsave }, + { "frestore", &jit_disable.frestore }, + { "fmove", &jit_disable.fmove }, + { "fmovec", &jit_disable.fmovec }, + { "fmovem", &jit_disable.fmovem }, + { "fmovecr", &jit_disable.fmovecr }, + { "fint", &jit_disable.fint }, + { "fsinh", &jit_disable.fsinh }, + { "fintrz", &jit_disable.fintrz }, + { "fsqrt", &jit_disable.fsqrt }, + { "flognp1", &jit_disable.flognp1 }, + { "fetoxm1", &jit_disable.fetoxm1 }, + { "ftanh", &jit_disable.ftanh }, + { "fatan", &jit_disable.fatan }, + { "fasin", &jit_disable.fasin }, + { "fatanh", &jit_disable.fatanh }, + { "fsin", &jit_disable.fsin }, + { "ftan", &jit_disable.ftan }, + { "fetox", &jit_disable.fetox }, + { "ftwotox", &jit_disable.ftwotox }, + { "ftentox", &jit_disable.ftentox }, + { "flogn", &jit_disable.flogn }, + { "flog10", &jit_disable.flog10 }, + { "flog2", &jit_disable.flog2 }, + { "fabs", &jit_disable.fabs }, + { "fcosh", &jit_disable.fcosh }, + { "fneg", &jit_disable.fneg }, + { "facos", &jit_disable.facos }, + { "fcos", &jit_disable.fcos }, + { "fgetexp", &jit_disable.fgetexp }, + { "fgetman", &jit_disable.fgetman }, + { "fdiv", &jit_disable.fdiv }, + { "fmod", &jit_disable.fmod }, + { "fadd", &jit_disable.fadd }, + { "fmul", &jit_disable.fmul }, + { "fsgldiv", &jit_disable.fsgldiv }, + { "frem", &jit_disable.frem }, + { "fscale", &jit_disable.fscale }, + { "fsglmul", &jit_disable.fsglmul }, + { "fsub", &jit_disable.fsub }, + { "fsincos", &jit_disable.fsincos }, + { "fcmp", &jit_disable.fcmp }, + { "ftst", &jit_disable.ftst }, +}; + +static bool read_fpu_opcode(const char **pp) +{ + const char *p = *pp; + const char *end; + size_t len; + unsigned int i; + + end = p; + while (*end != '\0' && *end != ',') + end++; + len = end - p; + if (*end != '\0') + end++; + for (i = 0; i < (sizeof(jit_opcodes) / sizeof(jit_opcodes[0])); i++) + { + if (len == strlen(jit_opcodes[i].name) && strnicmp(jit_opcodes[i].name, p, len) == 0) + { + *jit_opcodes[i].disabled = true; + jit_log(" : disabled %s", jit_opcodes[i].name); + *pp = end; + return true; + } + } + return false; +} +#endif + static bool merge_blacklist() { #ifdef UAE const char *blacklist = ""; #else const char *blacklist = bx_options.jit.jitblacklist; +#endif +#ifdef USE_JIT_FPU + for (unsigned int i = 0; i < (sizeof(jit_opcodes) / sizeof(jit_opcodes[0])); i++) + *jit_opcodes[i].disabled = false; #endif if (blacklist[0] != '\0') { const char *p = blacklist; @@ -3974,7 +4211,14 @@ static bool merge_blacklist() int opcode1 = read_opcode(p); if (opcode1 < 0) + { +#ifdef USE_JIT_FPU + if (read_fpu_opcode(&p)) + continue; +#endif + bug(" : invalid opcode %s", p); return false; + } p += 4; int opcode2 = opcode1; @@ -3982,7 +4226,10 @@ static bool merge_blacklist() p++; opcode2 = read_opcode(p); if (opcode2 < 0) + { + bug(" : invalid opcode %s", p); return false; + } p += 4; } @@ -4005,6 +4252,12 @@ static bool merge_blacklist() void build_comp(void) { +#ifdef FSUAE + if (!g_fs_uae_jit_compiler) { + jit_log("JIT: JIT compiler is not enabled"); + return; + } +#endif int i; unsigned long opcode; const struct comptbl* tbl=op_smalltbl_0_comp_ff; @@ -4014,13 +4267,12 @@ void build_comp(void) unsigned int cpu_level = 4; // 68040 const struct cputbl *nfctbl = op_smalltbl_0_nf; #else + unsigned int cpu_level = (currprefs.cpu_model - 68000) / 10; + if (cpu_level > 4) + cpu_level--; #ifdef NOFLAGS_SUPPORT - struct comptbl *nfctbl = (currprefs.cpu_level >= 5 ? op_smalltbl_0_nf - : currprefs.cpu_level == 4 ? op_smalltbl_1_nf - : (currprefs.cpu_level == 2 || currprefs.cpu_level == 3) ? op_smalltbl_2_nf - : currprefs.cpu_level == 1 ? op_smalltbl_3_nf - : ! currprefs.cpu_compatible ? op_smalltbl_4_nf - : op_smalltbl_5_nf); + extern const struct cputbl *uaegetjitcputbl(void); + const struct cputbl *nfctbl = uaegetjitcputbl(); #endif #endif // Initialize target CPU (check for features, e.g. CMOV, rat stalls) @@ -4043,30 +4295,16 @@ void build_comp(void) #endif prop[opcode].use_flags = FLAG_ALL; prop[opcode].set_flags = FLAG_ALL; -#ifdef UAE - prop[opcode].is_jump=1; -#else prop[opcode].cflow = fl_trap; // ILLEGAL instructions do trap -#endif } for (i = 0; tbl[i].opcode < 65536; i++) { -#ifdef UAE - int isjmp = (tbl[i].specific & COMP_OPCODE_ISJUMP); - int isaddx = (tbl[i].specific & COMP_OPCODE_ISADDX); - int iscjmp = (tbl[i].specific & COMP_OPCODE_ISCJUMP); - - prop[cft_map(tbl[i].opcode)].is_jump = isjmp; - prop[cft_map(tbl[i].opcode)].is_const_jump = iscjmp; - prop[cft_map(tbl[i].opcode)].is_addx = isaddx; -#else int cflow = table68k[tbl[i].opcode].cflow; if (follow_const_jumps && (tbl[i].specific & COMP_OPCODE_ISCJUMP)) cflow = fl_const_jump; else cflow &= ~fl_const_jump; prop[cft_map(tbl[i].opcode)].cflow = cflow; -#endif bool uses_fpu = (tbl[i].specific & COMP_OPCODE_USES_FPU) != 0; if (uses_fpu && avoid_fpu) @@ -4082,13 +4320,13 @@ void build_comp(void) else nfcompfunctbl[cft_map(nftbl[i].opcode)] = nftbl[i].handler; #ifdef NOFLAGS_SUPPORT - nfcpufunctbl[cft_map(nftbl[i].opcode)] = nfctbl[i].handler; + nfcpufunctbl[cft_map(nftbl[i].opcode)] = nfctbl[i].handler_nf; #endif } #ifdef NOFLAGS_SUPPORT - for (i = 0; nfctbl[i].handler; i++) { - nfcpufunctbl[cft_map(nfctbl[i].opcode)] = nfctbl[i].handler; + for (i = 0; nfctbl[i].handler_nf; i++) { + nfcpufunctbl[cft_map(nfctbl[i].opcode)] = nfctbl[i].handler_nf; } #endif @@ -4099,17 +4337,8 @@ void build_comp(void) cpuop_func *nfcf; #endif int isaddx; -#ifdef UAE - int isjmp,iscjmp; -#else int cflow; -#endif -#ifdef UAE - int cpu_level = (currprefs.cpu_model - 68000) / 10; - if (cpu_level > 4) - cpu_level--; -#endif if ((instrmnem)table68k[opcode].mnemo == i_ILLG || table68k[opcode].clev > cpu_level) continue; @@ -4121,15 +4350,8 @@ void build_comp(void) #endif isaddx = prop[cft_map(table68k[opcode].handler)].is_addx; prop[cft_map(opcode)].is_addx = isaddx; -#ifdef UAE - isjmp = prop[cft_map(table68k[opcode].handler)].is_jump; - iscjmp = prop[cft_map(table68k[opcode].handler)].is_const_jump; - prop[cft_map(opcode)].is_jump = isjmp; - prop[cft_map(opcode)].is_const_jump = iscjmp; -#else cflow = prop[cft_map(table68k[opcode].handler)].cflow; prop[cft_map(opcode)].cflow = cflow; -#endif compfunctbl[cft_map(opcode)] = f; nfcompfunctbl[cft_map(opcode)] = nff; #ifdef NOFLAGS_SUPPORT @@ -4142,17 +4364,13 @@ void build_comp(void) prop[cft_map(opcode)].use_flags = table68k[opcode].flaglive; /* Unconditional jumps don't evaluate condition codes, so they * don't actually use any flags themselves */ -#ifdef UAE - if (prop[cft_map(opcode)].is_const_jump) -#else if (prop[cft_map(opcode)].cflow & fl_const_jump) -#endif prop[cft_map(opcode)].use_flags = 0; } #ifdef NOFLAGS_SUPPORT - for (i = 0; nfctbl[i].handler != NULL; i++) { + for (i = 0; nfctbl[i].handler_nf != NULL; i++) { if (nfctbl[i].specific) - nfcpufunctbl[cft_map(tbl[i].opcode)] = nfctbl[i].handler; + nfcpufunctbl[cft_map(tbl[i].opcode)] = nfctbl[i].handler_nf; } #endif @@ -4161,7 +4379,7 @@ void build_comp(void) { jit_log(" : blacklist merge failure!"); } - + count=0; for (opcode = 0; opcode < 65536; opcode++) { if (compfunctbl[cft_map(opcode)]) @@ -4199,12 +4417,12 @@ void build_comp(void) } -static void flush_icache_none(int) +static void flush_icache_none(int v) { /* Nothing to do. */ } -void flush_icache_hard(int n) +void flush_icache_hard(int v) { blockinfo* bi, *dbi; @@ -4212,7 +4430,6 @@ void flush_icache_hard(int n) jit_log("JIT: Flush Icache_hard(%d/%x/%p), %u KB", n,regs.pc,regs.pc_p,current_cache_size/1024); #endif - UNUSED(n); bi=active; while(bi) { cache_tags[cacheline(bi->pc_p)].handler=(cpuop_func*)popall_execute_normal; @@ -4249,21 +4466,11 @@ void flush_icache_hard(int n) we simply mark everything as "needs to be checked". */ -#ifdef WINUAE_ARANYM -static inline void flush_icache_lazy(int) -#else -void flush_icache(int n) -#endif +static inline void flush_icache_lazy(int v) { blockinfo* bi; blockinfo* bi2; -#ifdef UAE - if (currprefs.comp_hardflush) { - flush_icache_hard(n); - return; - } -#endif if (!active) return; @@ -4298,10 +4505,9 @@ void flush_icache(int n) active=NULL; } -#ifdef UAE -static -#endif -void flush_icache_range(uae_u32 start, uae_u32 length) + +#if 0 +static void flush_icache_range(uae_u32 start, uae_u32 length) { if (!active) return; @@ -4334,24 +4540,23 @@ void flush_icache_range(uae_u32 start, uae_u32 length) UNUSED(start); UNUSED(length); #endif - flush_icache(-1); + flush_icache(); } +#endif -/* -static void catastrophe(void) -{ - jit_abort("catastprophe"); -} -*/ int failure; #ifdef UAE +#if defined(HAVE_GET_WORD_UNSWAPPED) +#define DO_GET_OPCODE(a) (do_get_mem_word_unswapped((uae_u16*)(a))) +#else static inline unsigned int get_opcode_cft_map(unsigned int f) { - return ((f >> 8) & 255) | ((f & 255) << 8); + return do_byteswap_16(f); } #define DO_GET_OPCODE(a) (get_opcode_cft_map((uae_u16)*(a))) +#endif #else #if defined(HAVE_GET_WORD_UNSWAPPED) && !defined(FULLMMU) # define DO_GET_OPCODE(a) (do_get_mem_word_unswapped((uae_u16 *)(a))) @@ -4378,11 +4583,7 @@ void compiler_dumpstate(void) jit_log(" "); jit_log("### M68k processor state"); -#ifdef UAE - m68k_dumpstate(NULL); -#else m68k_dumpstate(stderr, 0); -#endif jit_log(" "); jit_log("### Block in Atari address space"); @@ -4397,6 +4598,75 @@ void compiler_dumpstate(void) } #endif + +#if 0 /* debugging helpers; activate as needed */ +static void print_exc_frame(uae_u32 opcode) +{ + int nr = (opcode & 0x0f) + 32; + if (nr != 0x45 && /* Timer-C */ + nr != 0x1c && /* VBL */ + nr != 0x46) /* ACIA */ + { + memptr sp = m68k_areg(regs, 7); + uae_u16 sr = get_word(sp); + fprintf(stderr, "Exc:%02x SP: %08x USP: %08x SR: %04x PC: %08x Format: %04x", nr, sp, regs.usp, sr, get_long(sp + 2), get_word(sp + 6)); + if (nr >= 32 && nr < 48) + { + fprintf(stderr, " Opcode: $%04x", sr & 0x2000 ? get_word(sp + 8) : get_word(regs.usp)); + } + fprintf(stderr, "\n"); + } +} + +static void push_all_nat(void) +{ + raw_pushfl(); + raw_push_l_r(EAX_INDEX); + raw_push_l_r(ECX_INDEX); + raw_push_l_r(EDX_INDEX); + raw_push_l_r(EBX_INDEX); + raw_push_l_r(EBP_INDEX); + raw_push_l_r(EDI_INDEX); + raw_push_l_r(ESI_INDEX); + raw_push_l_r(R8_INDEX); + raw_push_l_r(R9_INDEX); + raw_push_l_r(R10_INDEX); + raw_push_l_r(R11_INDEX); + raw_push_l_r(R12_INDEX); + raw_push_l_r(R13_INDEX); + raw_push_l_r(R14_INDEX); + raw_push_l_r(R15_INDEX); +} + +static void pop_all_nat(void) +{ + raw_pop_l_r(R15_INDEX); + raw_pop_l_r(R14_INDEX); + raw_pop_l_r(R13_INDEX); + raw_pop_l_r(R12_INDEX); + raw_pop_l_r(R11_INDEX); + raw_pop_l_r(R10_INDEX); + raw_pop_l_r(R9_INDEX); + raw_pop_l_r(R8_INDEX); + raw_pop_l_r(ESI_INDEX); + raw_pop_l_r(EDI_INDEX); + raw_pop_l_r(EBP_INDEX); + raw_pop_l_r(EBX_INDEX); + raw_pop_l_r(EDX_INDEX); + raw_pop_l_r(ECX_INDEX); + raw_pop_l_r(EAX_INDEX); + raw_popfl(); +} +#endif + +#if 0 +static void print_inst(void) +{ + disasm_m68k_block(regs.fault_pc + (uint8 *)MEMBaseDiff, 1); +} +#endif + + #ifdef UAE void compile_block(cpu_history *pc_hist, int blocklen, int totcycles) { @@ -4435,7 +4705,7 @@ static void compile_block(cpu_history* pc_hist, int blocklen) redo_current_block=0; if (current_compile_p >= MAX_COMPILE_PTR) - flush_icache_hard(7); + flush_icache_hard(3); alloc_blockinfos(); @@ -4551,12 +4821,12 @@ static void compile_block(cpu_history* pc_hist, int blocklen) #ifdef USE_CPU_EMUL_SERVICES compemu_raw_sub_l_mi((uintptr)&emulated_ticks,blocklen); compemu_raw_jcc_b_oponly(NATIVE_CC_GT); - uae_s8 *branchadd=(uae_s8*)get_target(); + uae_u8 *branchadd=get_target(); skip_byte(); raw_dec_sp(STACK_SHADOW_SPACE); compemu_raw_call((uintptr)cpu_do_check_ticks); raw_inc_sp(STACK_SHADOW_SPACE); - *branchadd=(uintptr)get_target()-((uintptr)branchadd+1); + *branchadd=get_target()-(branchadd+1); #endif #ifdef JIT_DEBUG @@ -4597,8 +4867,8 @@ static void compile_block(cpu_history* pc_hist, int blocklen) remove_all_offsets(); prepare_for_call_1(); prepare_for_call_2(); - raw_mov_l_ri(REG_PAR1, ((uintptr)(pc_hist[i].location)) - MEMBaseDiff); - raw_mov_w_ri(REG_PAR2, opcode); + raw_mov_l_ri(REG_PAR1, (memptr)((uintptr)pc_hist[i].location - MEMBaseDiff)); + raw_mov_w_ri(REG_PAR2, cft_map(opcode)); raw_dec_sp(STACK_SHADOW_SPACE); compemu_raw_call((uintptr)m68k_record_step); raw_inc_sp(STACK_SHADOW_SPACE); @@ -4613,7 +4883,16 @@ static void compile_block(cpu_history* pc_hist, int blocklen) init_comp(); } was_comp=1; - + +#if defined(HAVE_DISASM_NATIVE) && defined(HAVE_DISASM_M68K) +/* debugging helpers; activate as needed */ +#if 1 + disasm_this_inst = false; + const uae_u8 *start_m68k_thisinst = (const uae_u8 *)pc_hist[i].location; + uae_u8 *start_native_thisinst = get_target(); +#endif +#endif + #ifdef WINUAE_ARANYM bool isnop = do_get_mem_word(pc_hist[i].location) == 0x4e71 || ((i + 1) < blocklen && do_get_mem_word(pc_hist[i+1].location) == 0x4e71); @@ -4634,7 +4913,6 @@ static void compile_block(cpu_history* pc_hist, int blocklen) flush(1); was_comp=0; #endif - #ifdef WINUAE_ARANYM /* * workaround for buserror handling: on a "nop", write registers back @@ -4645,6 +4923,44 @@ static void compile_block(cpu_history* pc_hist, int blocklen) nop(); was_comp=0; } +#endif +#if defined(HAVE_DISASM_NATIVE) && defined(HAVE_DISASM_M68K) + +/* debugging helpers; activate as needed */ +#if 0 + disasm_m68k_block(start_m68k_thisinst, 1); + push_all_nat(); + compemu_raw_mov_l_mi(uae_p32(®s.fault_pc), (uintptr)start_m68k_thisinst - MEMBaseDiff); + raw_dec_sp(STACK_SHADOW_SPACE); + compemu_raw_call(uae_p32(print_instn)); + raw_inc_sp(STACK_SHADOW_SPACE); + pop_all_nat(); +#endif + + if (disasm_this_inst) + { + disasm_m68k_block(start_m68k_thisinst, 1); +#if 1 + disasm_native_block(start_native_thisinst, get_target() - start_native_thisinst); +#endif + +#if 0 + push_all_nat(); + + raw_dec_sp(STACK_SHADOW_SPACE); + compemu_raw_mov_l_ri(REG_PAR1, (uae_u32)cft_map(opcode)); + compemu_raw_call((uintptr)print_exc_frame); + raw_inc_sp(STACK_SHADOW_SPACE); + + pop_all_nat(); +#endif + + if (failure) + { + bug("(discarded)"); + target = start_native_thisinst; + } + } #endif } @@ -4671,22 +4987,22 @@ static void compile_block(cpu_history* pc_hist, int blocklen) #endif if (i < blocklen - 1) { - uae_s8* branchadd; + uae_u8* branchadd; - /* if (SPCFLAGS_TEST(SPCFLAG_STOP)) popall_do_nothing() */ - compemu_raw_mov_l_rm(0,(uintptr)specflags); + /* if (SPCFLAGS_TEST(SPCFLAG_ALL)) popall_do_nothing() */ + compemu_raw_mov_l_rm(0, (uintptr)specflags); compemu_raw_test_l_rr(0,0); #if defined(USE_DATA_BUFFER) data_check_end(8, 64); // just a pessimistic guess... #endif compemu_raw_jz_b_oponly(); - branchadd=(uae_s8*)get_target(); + branchadd=get_target(); skip_byte(); #ifdef UAE raw_sub_l_mi(uae_p32(&countdown),scaled_cycles(totcycles)); #endif compemu_raw_jmp((uintptr)popall_do_nothing); - *branchadd=(uintptr)get_target()-(uintptr)branchadd-1; + *branchadd = get_target() - (branchadd + 1); } } } @@ -4887,7 +5203,7 @@ static void compile_block(cpu_history* pc_hist, int blocklen) } #endif - current_cache_size += get_target() - (uae_u8 *)current_compile_p; + current_cache_size += get_target() - current_compile_p; #ifdef JIT_DEBUG bi->direct_handler_size = get_target() - (uae_u8 *)current_block_start_target; @@ -4939,7 +5255,7 @@ static void compile_block(cpu_history* pc_hist, int blocklen) /* We will flush soon, anyway, so let's do it now */ if (current_compile_p >= MAX_COMPILE_PTR) - flush_icache_hard(7); + flush_icache_hard(3); bi->status=BI_ACTIVE; if (redo_current_block) @@ -4953,6 +5269,11 @@ static void compile_block(cpu_history* pc_hist, int blocklen) do_extra_cycles(totcycles); #endif } + +#ifdef USE_CPU_EMUL_SERVICES + /* Account for compilation time */ + cpu_do_check_ticks(); +#endif } #ifdef UAE @@ -4972,7 +5293,7 @@ void exec_nostats(void) for (;;) { uae_u32 opcode = GET_OPCODE; #ifdef FLIGHT_RECORDER - m68k_record_step(m68k_getpc(), opcode); + m68k_record_step(m68k_getpc(), cft_map(opcode)); #endif (*cpufunctbl[opcode])(opcode); cpu_check_ticks(); @@ -5002,7 +5323,7 @@ void execute_normal(void) pc_hist[blocklen++].location = (uae_u16 *)regs.pc_p; uae_u32 opcode = GET_OPCODE; #ifdef FLIGHT_RECORDER - m68k_record_step(m68k_getpc(), opcode); + m68k_record_step(m68k_getpc(), cft_map(opcode)); #endif (*cpufunctbl[opcode])(opcode); cpu_check_ticks(); @@ -5064,7 +5385,7 @@ setjmpagain: regs.fault_pc, regs.mmu_fault_addr, get_long (regs.vbr + 4*prb), regs.regs[15]); - flush_icache(0); + flush_icache(); Exception(prb, 0); goto setjmpagain; } diff --git a/jit/gencomp.cpp b/jit/gencomp.cpp index 904508ce..678e5d2f 100644 --- a/jit/gencomp.cpp +++ b/jit/gencomp.cpp @@ -6,7 +6,7 @@ * * Adaptation for ARAnyM/ARM, copyright 2001-2014 * Milan Jurik, Jens Heitmann - * + * * Adaptation for Basilisk II and improvements, copyright 2000-2005 * Gwenole Beauchesne * @@ -43,60 +43,65 @@ #undef abort #ifdef UAE -/* -#define DISABLE_I_OR_AND_EOR -#define DISABLE_I_SUB -#define DISABLE_I_SUBA -#define DISABLE_I_SUBX -#define DISABLE_I_ADD -#define DISABLE_I_ADDA -#define DISABLE_I_ADDX -#define DISABLE_I_NEG -#define DISABLE_I_NEGX -#define DISABLE_I_CLR -#define DISABLE_I_NOT -#define DISABLE_I_TST -#define DISABLE_I_BCHG_BCLR_BSET_BTST -#define DISABLE_I_CMPM_CMP -#define DISABLE_I_CMPA -#define DISABLE_I_MOVE -#define DISABLE_I_MOVEA -#define DISABLE_I_SWAP -#define DISABLE_I_EXG -#define DISABLE_I_EXT -#define DISABLE_I_MVEL -#define DISABLE_I_MVMLE -#define DISABLE_I_RTD -#define DISABLE_I_LINK -#define DISABLE_I_UNLK -#define DISABLE_I_RTS -#define DISABLE_I_JSR -#define DISABLE_I_JMP -#define DISABLE_I_BSR -#define DISABLE_I_BCC -#define DISABLE_I_LEA -#define DISABLE_I_PEA -#define DISABLE_I_DBCC -#define DISABLE_I_SCC -#define DISABLE_I_MULU -#define DISABLE_I_MULS -#define DISABLE_I_ASR -#define DISABLE_I_ASL -#define DISABLE_I_LSR -#define DISABLE_I_LSL -#define DISABLE_I_ROL -#define DISABLE_I_ROR -#define DISABLE_I_MULL -#define DISABLE_I_FPP -#define DISABLE_I_FBCC -#define DISABLE_I_FSCC -#define DISABLE_I_MOVE16 -*/ + /* + #define DISABLE_I_OR_AND_EOR + #define DISABLE_I_SUB + #define DISABLE_I_SUBA + #define DISABLE_I_SUBX + #define DISABLE_I_ADD + #define DISABLE_I_ADDA + #define DISABLE_I_ADDX + #define DISABLE_I_NEG + #define DISABLE_I_NEGX + #define DISABLE_I_CLR + #define DISABLE_I_NOT + #define DISABLE_I_TST + #define DISABLE_I_BCHG_BCLR_BSET_BTST + #define DISABLE_I_CMPM_CMP + #define DISABLE_I_CMPA + #define DISABLE_I_MOVE + #define DISABLE_I_MOVEA + #define DISABLE_I_SWAP + #define DISABLE_I_EXG + #define DISABLE_I_EXT + #define DISABLE_I_MVEL + #define DISABLE_I_MVMLE + #define DISABLE_I_RTD + #define DISABLE_I_LINK + #define DISABLE_I_UNLK + #define DISABLE_I_RTS + #define DISABLE_I_JSR + #define DISABLE_I_JMP + #define DISABLE_I_BSR + #define DISABLE_I_BCC + #define DISABLE_I_LEA + #define DISABLE_I_PEA + #define DISABLE_I_DBCC + #define DISABLE_I_SCC + #define DISABLE_I_MULU + #define DISABLE_I_MULS + #define DISABLE_I_ASR + #define DISABLE_I_ASL + #define DISABLE_I_LSR + #define DISABLE_I_LSL + #define DISABLE_I_ROL + #define DISABLE_I_ROR + #define DISABLE_I_MULL + #define DISABLE_I_FPP + #define DISABLE_I_FBCC + #define DISABLE_I_FSCC + #define DISABLE_I_MOVE16 + */ + #endif /* UAE */ #ifdef UAE #define JIT_PATH "jit/" +#ifdef FSUAE +#define GEN_PATH "gen/" +#else #define GEN_PATH "jit/" +#endif #define RETURN "return 0;" #define RETTYPE "uae_u32" #define NEXT_CPU_LEVEL 5 @@ -106,14 +111,13 @@ #define RETURN "return;" #define RETTYPE "void" #define NEXT_CPU_LEVEL 4 -#define ua(s) s #endif #define BOOL_TYPE "int" #define failure global_failure=1 #define FAILURE global_failure=1 #define isjump global_isjump=1 -#define is_const_jump global_iscjump=1; +#define is_const_jump global_iscjump=1 #define isaddx global_isaddx=1 #define uses_cmov global_cmov=1 #define mayfail global_mayfail=1 @@ -132,39 +136,117 @@ static int global_fpu; static char endstr[1000]; static char lines[100000]; -static int comp_index=0; #include "flags_x86.h" -static int cond_codes[]={-1,-1, - NATIVE_CC_HI,NATIVE_CC_LS, - NATIVE_CC_CC,NATIVE_CC_CS, - NATIVE_CC_NE,NATIVE_CC_EQ, - -1,-1, - NATIVE_CC_PL,NATIVE_CC_MI, - NATIVE_CC_GE,NATIVE_CC_LT, - NATIVE_CC_GT,NATIVE_CC_LE - }; - -static void comprintf(const char* format, ...) +#ifndef __attribute__ +# ifndef __GNUC__ +# define __attribute__(x) +# endif +#endif + +#define GENA_GETV_NO_FETCH 0 +#define GENA_GETV_FETCH 1 +#define GENA_GETV_FETCH_ALIGN 2 +#define GENA_MOVEM_DO_INC 0 +#define GENA_MOVEM_NO_INC 1 +#define GENA_MOVEM_MOVE16 2 + + +static int cond_codes[] = { -1, -1, +NATIVE_CC_HI, NATIVE_CC_LS, +NATIVE_CC_CC, NATIVE_CC_CS, +NATIVE_CC_NE, NATIVE_CC_EQ, +-1, -1, +NATIVE_CC_PL, NATIVE_CC_MI, +NATIVE_CC_GE, NATIVE_CC_LT, +NATIVE_CC_GT, NATIVE_CC_LE +}; + +static int brace_level; + +static char outbuffer[30000]; + +static void comprintf(const char *format, ...) { - va_list args; + char outbuf[1000]; + va_list parms; + va_start(parms, format); + _vsnprintf(outbuf, sizeof(outbuf) - 1, format, parms); + outbuf[sizeof(outbuf) - 1] = 0; + va_end(parms); + + char *p = outbuf; + bool firstspace = true; + while (*p) { + char v = *p; + if (v == '\t' || (v == ' ' && p[1] == ' ') || (firstspace && v == ' ')) { + memmove(p, p + 1, strlen(p + 1) + 1); + } else { + firstspace = false; + p++; + } + } + + p = outbuf; + for (;;) { + char *pe = p; + int islf = 0; + while (*pe != 0 && *pe != '\n') { + pe++; + } + if (*pe == '\n') { + islf = 1; + *pe = 0; + } + + char outbuf2[1000]; + strcpy(outbuf2, p); + outbuf2[pe - p] = 0; + + if (outbuf2[0]) { + char *ps = outbuf2; + while (*ps) { + char v = *ps; + if (v == '}') { + brace_level--; + } + ps++; + } + for (int i = 0; i < brace_level; i++) { + strcat(outbuffer, "\t"); + } + strcat(outbuffer, outbuf2); + + ps = outbuf2; + while (*ps) { + char v = *ps; + if (v == '{') { + brace_level++; + } + ps++; + } + } - va_start(args,format); - comp_index+=vsprintf(lines+comp_index,format,args); + if (islf) { + strcat(outbuffer, "\n"); + pe++; + } + if (*pe == 0) + break; + p = pe; + } } static void com_discard(void) { - comp_index=0; + outbuffer[0] = 0; } static void com_flush(void) { - int i; - for (i=0;i 0); - n_braces--; - comprintf ("}"); + assert(n_braces > 0); + n_braces--; + comprintf("}\n"); } -static void -finish_braces (void) +static void finish_braces(void) { - while (n_braces > 0) - close_brace (); + while (n_braces > 0) + close_brace(); } static inline void gen_update_next_handler(void) { - return; /* Can anything clever be done here? */ + return; /* Can anything clever be done here? */ } -static void gen_writebyte (const char* address, const char* source) +static void gen_writebyte(const char *address, const char *source) { - comprintf("\twritebyte(%s,%s,scratchie);\n",address,source); + comprintf("\twritebyte(%s, %s, scratchie);\n", address, source); } -static void gen_writeword (const char* address, const char* source) +static void gen_writeword(const char *address, const char *source) { - comprintf("\twriteword(%s,%s,scratchie);\n",address,source); + comprintf("\twriteword(%s, %s, scratchie);\n", address, source); } -static void gen_writelong (const char* address, const char* source) +static void gen_writelong(const char *address, const char *source) { - comprintf("\twritelong(%s,%s,scratchie);\n",address,source); + comprintf("\twritelong(%s, %s, scratchie);\n", address, source); } -static void gen_readbyte (const char* address, const char* dest) +static void gen_readbyte(const char *address, const char *dest) { - comprintf("\treadbyte(%s,%s,scratchie);\n",address,dest); + comprintf("\treadbyte(%s, %s, scratchie);\n", address, dest); } -static void gen_readword (const char* address, const char* dest) +static void gen_readword(const char *address, const char *dest) { - comprintf("\treadword(%s,%s,scratchie);\n",address,dest); + comprintf("\treadword(%s,%s,scratchie);\n", address, dest); } -static void gen_readlong (const char* address, const char* dest) +static void gen_readlong(const char *address, const char *dest) { - comprintf("\treadlong(%s,%s,scratchie);\n",address,dest); + comprintf("\treadlong(%s, %s, scratchie);\n", address, dest); } static const char * -gen_nextilong (void) +gen_nextilong(void) { - static char buffer[80]; + static char buffer[80]; - sprintf (buffer, "comp_get_ilong((m68k_pc_offset+=4)-4)"); - insn_n_cycles += 4; + sprintf(buffer, "comp_get_ilong((m68k_pc_offset+=4)-4)"); + insn_n_cycles += 4; - long_opcode=1; - return buffer; + long_opcode = 1; + return buffer; } static const char * -gen_nextiword (void) +gen_nextiword(void) { - static char buffer[80]; + static char buffer[80]; - sprintf (buffer, "comp_get_iword((m68k_pc_offset+=2)-2)"); - insn_n_cycles+=2; + sprintf(buffer, "comp_get_iword((m68k_pc_offset+=2)-2)"); + insn_n_cycles += 2; - long_opcode=1; - return buffer; + long_opcode = 1; + return buffer; } static const char * -gen_nextibyte (void) +gen_nextibyte(void) { - static char buffer[80]; + static char buffer[80]; - sprintf (buffer, "comp_get_ibyte((m68k_pc_offset+=2)-2)"); - insn_n_cycles += 2; + sprintf(buffer, "comp_get_ibyte((m68k_pc_offset+=2)-2)"); + insn_n_cycles += 2; - long_opcode=1; - return buffer; + long_opcode = 1; + return buffer; } static void -swap_opcode (void) +swap_opcode(void) { #ifdef UAE /* no-op */ @@ -339,331 +417,370 @@ swap_opcode (void) #endif } -static void -sync_m68k_pc (void) +static void sync_m68k_pc(void) +{ + comprintf("if (m68k_pc_offset > SYNC_PC_OFFSET) {\n"); + comprintf("sync_m68k_pc();\n"); + comprintf("}\n"); +} + + +static void gen_set_fault_pc(void) +{ + start_brace(); + comprintf("\tsync_m68k_pc();\n"); + comprintf("\tuae_u32 retadd=start_pc+((char *)comp_pc_p-(char *)start_pc_p)+m68k_pc_offset;\n"); + comprintf("\tint ret=scratchie++;\n" + "\tmov_l_ri(ret,retadd);\n" + "\tmov_l_mr((uintptr)®s.fault_pc,ret);\n"); +} + + +static void make_sr(void) +{ + start_brace(); + comprintf("\tint sr = scratchie++;\n"); + comprintf("\tint tmp = scratchie++;\n"); + comprintf("\tcompemu_make_sr(sr, tmp);\n"); +} + + +static void disasm_this_inst(void) { - comprintf("\t if (m68k_pc_offset > SYNC_PC_OFFSET) sync_m68k_pc();\n"); + comprintf("\tdisasm_this_inst = true;\n"); } /* getv == 1: fetch data; getv != 0: check for odd address. If movem != 0, * the calling routine handles Apdi and Aipi modes. * gb-- movem == 2 means the same thing but for a MOVE16 instruction */ -static void -genamode (amodes mode, const char *reg, wordsizes size, const char *name, int getv, int movem) +static void genamode(amodes mode, const char *reg, wordsizes size, const char *name, int getv, int movem) { - start_brace (); - switch (mode) - { - case Dreg: /* Do we need to check dodgy here? */ - assert (!movem); - if (getv == 1 || getv==2) { - /* We generate the variable even for getv==2, so we can use - it as a destination for MOVE */ - comprintf ("\tint %s=%s;\n",name,reg); - } - return; - - case Areg: - assert (!movem); - if (getv == 1 || getv==2) { - /* see above */ - comprintf ("\tint %s=dodgy?scratchie++:%s+8;\n",name,reg); - if (getv==1) { - comprintf ("\tif (dodgy) \n"); - comprintf ("\t\tmov_l_rr(%s,%s+8);\n",name, reg); - } - } - return; - - case Aind: - comprintf ("\tint %sa=dodgy?scratchie++:%s+8;\n",name,reg); - comprintf ("\tif (dodgy) \n"); - comprintf ("\t\tmov_l_rr(%sa,%s+8);\n",name, reg); - break; - case Aipi: - comprintf ("\tint %sa=scratchie++;\n",name,reg); - comprintf ("\tmov_l_rr(%sa,%s+8);\n",name, reg); - break; - case Apdi: - switch (size) + start_brace(); + switch (mode) { - case sz_byte: - if (movem) { - comprintf ("\tint %sa=dodgy?scratchie++:%s+8;\n",name,reg); - comprintf ("\tif (dodgy) \n"); - comprintf("\tmov_l_rr(%sa,8+%s);\n",name,reg); - } - else { - start_brace(); - comprintf ("\tint %sa=dodgy?scratchie++:%s+8;\n",name,reg); - comprintf("\tlea_l_brr(%s+8,%s+8,(uae_s32)-areg_byteinc[%s]);\n",reg,reg,reg); - comprintf ("\tif (dodgy) \n"); - comprintf("\tmov_l_rr(%sa,8+%s);\n",name,reg); - } - break; - case sz_word: - if (movem) { - comprintf ("\tint %sa=dodgy?scratchie++:%s+8;\n",name,reg); - comprintf ("\tif (dodgy) \n"); - comprintf("\tmov_l_rr(%sa,8+%s);\n",name,reg); - } - else { - start_brace(); - comprintf ("\tint %sa=dodgy?scratchie++:%s+8;\n",name,reg); - comprintf("\tlea_l_brr(%s+8,%s+8,-2);\n",reg,reg); - comprintf ("\tif (dodgy) \n"); - comprintf("\tmov_l_rr(%sa,8+%s);\n",name,reg); - } - break; - case sz_long: - if (movem) { - comprintf ("\tint %sa=dodgy?scratchie++:%s+8;\n",name,reg); - comprintf ("\tif (dodgy) \n"); - comprintf("\tmov_l_rr(%sa,8+%s);\n",name,reg); - } - else { - start_brace(); - comprintf ("\tint %sa=dodgy?scratchie++:%s+8;\n",name,reg); - comprintf("\tlea_l_brr(%s+8,%s+8,-4);\n",reg,reg); - comprintf ("\tif (dodgy) \n"); - comprintf("\tmov_l_rr(%sa,8+%s);\n",name,reg); - } - break; - default: - assert(0); - } - break; - case Ad16: - comprintf("\tint %sa=scratchie++;\n",name); - comprintf("\tmov_l_rr(%sa,8+%s);\n",name,reg); - comprintf("\tlea_l_brr(%sa,%sa,(uae_s32)(uae_s16)%s);\n",name,name,gen_nextiword()); - break; - case Ad8r: - comprintf("\tint %sa=scratchie++;\n",name); - comprintf("\tcalc_disp_ea_020(%s+8,%s,%sa,scratchie);\n", - reg,gen_nextiword(),name); - break; + case Dreg: /* Do we need to check dodgy here? */ + assert(movem == GENA_MOVEM_DO_INC); + if (getv == GENA_GETV_FETCH || getv == GENA_GETV_FETCH_ALIGN) + { + /* We generate the variable even for getv==2, so we can use + it as a destination for MOVE */ + comprintf("\tint %s = %s;\n", name, reg); + } + return; - case PC16: - comprintf("\tint %sa=scratchie++;\n",name); - comprintf("\tuae_u32 address=start_pc+((char *)comp_pc_p-(char *)start_pc_p)+m68k_pc_offset;\n"); - comprintf ("\tuae_s32 PC16off = (uae_s32)(uae_s16)%s;\n", gen_nextiword ()); - comprintf("\tmov_l_ri(%sa,address+PC16off);\n",name); - break; + case Areg: + assert(movem == GENA_MOVEM_DO_INC); + if (getv == GENA_GETV_FETCH || getv == GENA_GETV_FETCH_ALIGN) + { + /* see above */ + comprintf("\tint %s = dodgy ? scratchie++ : %s + 8;\n", name, reg); + if (getv == GENA_GETV_FETCH) + { + comprintf("\tif (dodgy) \n"); + comprintf("\t\tmov_l_rr(%s, %s + 8);\n", name, reg); + } + } + return; - case PC8r: - comprintf("\tint pctmp=scratchie++;\n"); - comprintf("\tint %sa=scratchie++;\n",name); - comprintf("\tuae_u32 address=start_pc+((char *)comp_pc_p-(char *)start_pc_p)+m68k_pc_offset;\n"); - start_brace(); - comprintf("\tmov_l_ri(pctmp,address);\n"); + case Aind: + comprintf("\tint %sa = dodgy ? scratchie++ : %s + 8;\n", name, reg); + comprintf("\tif (dodgy)\n"); + comprintf("\t\tmov_l_rr(%sa, %s + 8);\n", name, reg); + break; + case Aipi: + comprintf("\tint %sa = scratchie++;\n", name); + comprintf("\tmov_l_rr(%sa, %s + 8);\n", name, reg); + break; + case Apdi: + switch (size) + { + case sz_byte: + if (movem != GENA_MOVEM_DO_INC) + { + comprintf("\tint %sa = dodgy ? scratchie++ : %s + 8;\n", name, reg); + comprintf("\tif (dodgy)\n"); + comprintf("\t\tmov_l_rr(%sa, 8 + %s);\n", name, reg); + } else + { + start_brace(); + comprintf("\tint %sa = dodgy ? scratchie++ : %s + 8;\n", name, reg); + comprintf("\tlea_l_brr(%s + 8, %s + 8, (uae_s32)-areg_byteinc[%s]);\n", reg, reg, reg); + comprintf("\tif (dodgy)\n"); + comprintf("\t\tmov_l_rr(%sa, 8 + %s);\n", name, reg); + } + break; + case sz_word: + if (movem != GENA_MOVEM_DO_INC) + { + comprintf("\tint %sa=dodgy?scratchie++:%s+8;\n", name, reg); + comprintf("\tif (dodgy) \n"); + comprintf("\tmov_l_rr(%sa,8+%s);\n", name, reg); + } else + { + start_brace(); + comprintf("\tint %sa = dodgy ? scratchie++ : %s + 8;\n", name, reg); + comprintf("\tlea_l_brr(%s + 8, %s + 8, -2);\n", reg, reg); + comprintf("\tif (dodgy)\n"); + comprintf("\t\tmov_l_rr(%sa, 8 + %s);\n", name, reg); + } + break; + case sz_long: + if (movem != GENA_MOVEM_DO_INC) + { + comprintf("\tint %sa = dodgy ? scratchie++ : %s + 8;\n", name, reg); + comprintf("\tif (dodgy)\n"); + comprintf("\t\tmov_l_rr(%sa, 8 + %s);\n", name, reg); + } else + { + start_brace(); + comprintf("\tint %sa = dodgy ? scratchie++ : %s + 8;\n", name, reg); + comprintf("\tlea_l_brr(%s + 8, %s + 8, -4);\n", reg, reg); + comprintf("\tif (dodgy)\n"); + comprintf("\t\tmov_l_rr(%sa, 8 + %s);\n", name, reg); + } + break; + default: + assert(0); + break; + } + break; + case Ad16: + comprintf("\tint %sa = scratchie++;\n", name); + comprintf("\tmov_l_rr(%sa, 8 + %s);\n", name, reg); + comprintf("\tlea_l_brr(%sa, %sa, (uae_s32)(uae_s16)%s);\n", name, name, gen_nextiword()); + break; + case Ad8r: + comprintf("\tint %sa = scratchie++;\n", name); + comprintf("\tcalc_disp_ea_020(%s + 8, %s, %sa, scratchie);\n", reg, gen_nextiword(), name); + break; - comprintf("\tcalc_disp_ea_020(pctmp,%s,%sa,scratchie);\n", - gen_nextiword(),name); - break; - case absw: - comprintf ("\tint %sa = scratchie++;\n",name); - comprintf ("\tmov_l_ri(%sa,(uae_s32)(uae_s16)%s);\n", name, gen_nextiword ()); - break; - case absl: - comprintf ("\tint %sa = scratchie++;\n",name); - comprintf ("\tmov_l_ri(%sa,%s); /* absl */\n", name, gen_nextilong ()); - break; - case imm: - assert (getv == 1); - switch (size) - { - case sz_byte: - comprintf ("\tint %s = scratchie++;\n",name); - comprintf ("\tmov_l_ri(%s,(uae_s32)(uae_s8)%s);\n", name, gen_nextibyte ()); - break; - case sz_word: - comprintf ("\tint %s = scratchie++;\n",name); - comprintf ("\tmov_l_ri(%s,(uae_s32)(uae_s16)%s);\n", name, gen_nextiword ()); - break; - case sz_long: - comprintf ("\tint %s = scratchie++;\n",name); - comprintf ("\tmov_l_ri(%s,%s);\n", name, gen_nextilong ()); - break; - default: - assert(0); + case PC16: + comprintf("\tint %sa = scratchie++;\n", name); + comprintf("\tuae_u32 address = start_pc + ((char *)comp_pc_p - (char *)start_pc_p) + m68k_pc_offset;\n"); + comprintf("\tuae_s32 PC16off = (uae_s32)(uae_s16)%s;\n", gen_nextiword()); + comprintf("\tmov_l_ri(%sa, address + PC16off);\n", name); + break; + + case PC8r: + comprintf("\tint pctmp = scratchie++;\n"); + comprintf("\tint %sa = scratchie++;\n", name); + comprintf("\tuae_u32 address = start_pc + ((char *)comp_pc_p - (char *)start_pc_p) + m68k_pc_offset;\n"); + start_brace(); + comprintf("\tmov_l_ri(pctmp,address);\n"); + + comprintf("\tcalc_disp_ea_020(pctmp, %s, %sa, scratchie);\n", gen_nextiword(), name); + break; + case absw: + comprintf("\tint %sa = scratchie++;\n", name); + comprintf("\tmov_l_ri(%sa, (uae_s32)(uae_s16)%s);\n", name, gen_nextiword()); + break; + case absl: + comprintf("\tint %sa = scratchie++;\n", name); + comprintf("\tmov_l_ri(%sa, %s); /* absl */\n", name, gen_nextilong()); + break; + case imm: + assert(getv == GENA_GETV_FETCH); + switch (size) + { + case sz_byte: + comprintf("\tint %s = scratchie++;\n", name); + comprintf("\tmov_l_ri(%s, (uae_s32)(uae_s8)%s);\n", name, gen_nextibyte()); + break; + case sz_word: + comprintf("\tint %s = scratchie++;\n", name); + comprintf("\tmov_l_ri(%s, (uae_s32)(uae_s16)%s);\n", name, gen_nextiword()); + break; + case sz_long: + comprintf("\tint %s = scratchie++;\n", name); + comprintf("\tmov_l_ri(%s, %s);\n", name, gen_nextilong()); + break; + default: + assert(0); + break; + } + return; + case imm0: + assert(getv == GENA_GETV_FETCH); + comprintf("\tint %s = scratchie++;\n", name); + comprintf("\tmov_l_ri(%s, (uae_s32)(uae_s8)%s);\n", name, gen_nextibyte()); + return; + case imm1: + assert(getv == GENA_GETV_FETCH); + comprintf("\tint %s = scratchie++;\n", name); + comprintf("\tmov_l_ri(%s, (uae_s32)(uae_s16)%s);\n", name, gen_nextiword()); + return; + case imm2: + assert(getv == GENA_GETV_FETCH); + comprintf("\tint %s = scratchie++;\n", name); + comprintf("\tmov_l_ri(%s, %s);\n", name, gen_nextilong()); + return; + case immi: + assert(getv == GENA_GETV_FETCH); + comprintf("\tint %s = scratchie++;\n", name); + comprintf("\tmov_l_ri(%s, %s);\n", name, reg); + return; + default: + assert(0); + break; } - return; - case imm0: - assert (getv == 1); - comprintf ("\tint %s = scratchie++;\n",name); - comprintf ("\tmov_l_ri(%s,(uae_s32)(uae_s8)%s);\n", name, gen_nextibyte ()); - return; - case imm1: - assert (getv == 1); - comprintf ("\tint %s = scratchie++;\n",name); - comprintf ("\tmov_l_ri(%s,(uae_s32)(uae_s16)%s);\n", name, gen_nextiword ()); - return; - case imm2: - assert (getv == 1); - comprintf ("\tint %s = scratchie++;\n",name); - comprintf ("\tmov_l_ri(%s,%s);\n", name, gen_nextilong ()); - return; - case immi: - assert (getv == 1); - comprintf ("\tint %s = scratchie++;\n",name); - comprintf ("\tmov_l_ri(%s,%s);\n", name, reg); - return; - default: - assert(0); - } - - /* We get here for all non-reg non-immediate addressing modes to - * actually fetch the value. */ - if (getv == 1) - { - char astring[80]; - sprintf(astring,"%sa",name); - switch (size) + + /* We get here for all non-reg non-immediate addressing modes to + * actually fetch the value. */ + if (getv == GENA_GETV_FETCH) { - case sz_byte: - insn_n_cycles += 2; - break; - case sz_word: - insn_n_cycles += 2; - break; - case sz_long: - insn_n_cycles += 4; - break; - default: - assert(0); + char astring[80]; + sprintf(astring, "%sa", name); + switch (size) + { + case sz_byte: + insn_n_cycles += 2; + break; + case sz_word: + insn_n_cycles += 2; + break; + case sz_long: + insn_n_cycles += 4; + break; + default: + assert(0); + break; + } + start_brace(); + comprintf("\tint %s = scratchie++;\n", name); + switch (size) + { + case sz_byte: + gen_readbyte(astring, name); + break; + case sz_word: + gen_readword(astring, name); + break; + case sz_long: + gen_readlong(astring, name); + break; + default: + assert(0); + break; + } } - start_brace (); - comprintf("\tint %s=scratchie++;\n",name); - switch (size) + + /* We now might have to fix up the register for pre-dec or post-inc + * addressing modes. */ + if (movem == GENA_MOVEM_DO_INC) { - case sz_byte: - gen_readbyte(astring,name); - break; - case sz_word: - gen_readword(astring,name); - break; - case sz_long: - gen_readlong(astring,name); - break; - default: - assert(0); + switch (mode) + { + case Aipi: + switch (size) + { + case sz_byte: + comprintf("\tlea_l_brr(%s + 8,%s + 8, areg_byteinc[%s]);\n", reg, reg, reg); + break; + case sz_word: + comprintf("\tlea_l_brr(%s + 8, %s + 8, 2);\n", reg, reg); + break; + case sz_long: + comprintf("\tlea_l_brr(%s + 8, %s + 8, 4);\n", reg, reg); + break; + default: + assert(0); + break; + } + break; + case Apdi: + break; + default: + break; + } } - } +} - /* We now might have to fix up the register for pre-dec or post-inc - * addressing modes. */ - if (!movem) { -// MJ char x[160]; +static void genastore(const char *from, amodes mode, const char *reg, wordsizes size, const char *to) +{ switch (mode) { - case Aipi: - switch (size) - { - case sz_byte: - comprintf("\tlea_l_brr(%s+8,%s+8,areg_byteinc[%s]);\n",reg,reg,reg); - break; - case sz_word: - comprintf("\tlea_l_brr(%s+8,%s+8,2);\n",reg,reg,reg); + case Dreg: + switch (size) + { + case sz_byte: + comprintf("\tif(%s != %s)\n", reg, from); + comprintf("\t\tmov_b_rr(%s, %s);\n", reg, from); + break; + case sz_word: + comprintf("\tif(%s != %s)\n", reg, from); + comprintf("\t\tmov_w_rr(%s, %s);\n", reg, from); + break; + case sz_long: + comprintf("\tif(%s != %s)\n", reg, from); + comprintf("\t\tmov_l_rr(%s, %s);\n", reg, from); + break; + default: + assert(0); + break; + } break; - case sz_long: - comprintf("\tlea_l_brr(%s+8,%s+8,4);\n",reg,reg); + case Areg: + switch (size) + { + case sz_word: + comprintf("\tif(%s + 8 != %s)\n", reg, from); + comprintf("\t\tmov_w_rr(%s + 8, %s);\n", reg, from); + break; + case sz_long: + comprintf("\tif(%s + 8 != %s)\n", reg, from); + comprintf("\t\tmov_l_rr(%s + 8, %s);\n", reg, from); + break; + default: + assert(0); + break; + } break; - default: - assert(0); - } - break; - case Apdi: - break; - default: - break; - } - } -} -static void -genastore (const char *from, amodes mode, const char *reg, wordsizes size, const char *to) -{ - switch (mode) - { - case Dreg: - switch (size) + case Apdi: + case absw: + case PC16: + case PC8r: + case Ad16: + case Ad8r: + case Aipi: + case Aind: + case absl: { - case sz_byte: - comprintf("\tif(%s!=%s)\n",reg,from); - comprintf ("\t\tmov_b_rr(%s,%s);\n", reg, from); - break; - case sz_word: - comprintf("\tif(%s!=%s)\n",reg,from); - comprintf ("\t\tmov_w_rr(%s,%s);\n", reg, from); - break; - case sz_long: - comprintf("\tif(%s!=%s)\n",reg,from); - comprintf ("\t\tmov_l_rr(%s,%s);\n", reg, from); - break; - default: - assert(0); + char astring[80]; + sprintf(astring, "%sa", to); + + switch (size) + { + case sz_byte: + insn_n_cycles += 2; + gen_writebyte(astring, from); + break; + case sz_word: + insn_n_cycles += 2; + gen_writeword(astring, from); + break; + case sz_long: + insn_n_cycles += 4; + gen_writelong(astring, from); + break; + default: + assert(0); + break; + } } break; - case Areg: - switch (size) - { - case sz_word: - comprintf("\tif(%s+8!=%s)\n",reg,from); - comprintf ("\t\tmov_w_rr(%s+8,%s);\n", reg, from); - break; - case sz_long: - comprintf("\tif(%s+8!=%s)\n",reg,from); - comprintf ("\t\tmov_l_rr(%s+8,%s);\n", reg, from); - break; - default: - assert(0); + case imm: + case imm0: + case imm1: + case imm2: + case immi: + assert(0); + break; + default: + assert(0); + break; } - break; - - case Apdi: - case absw: - case PC16: - case PC8r: - case Ad16: - case Ad8r: - case Aipi: - case Aind: - case absl: - { - char astring[80]; - sprintf(astring,"%sa",to); - - switch (size) - { - case sz_byte: - insn_n_cycles += 2; - gen_writebyte(astring,from); - break; - case sz_word: - insn_n_cycles += 2; - gen_writeword(astring,from); - break; - case sz_long: - insn_n_cycles += 4; - gen_writelong(astring,from); - break; - default: - assert(0); - } - } - break; - case imm: - case imm0: - case imm1: - case imm2: - case immi: - assert(0); - break; - default: - assert(0); - } } static void genmov16(uae_u32 opcode, struct instr *curi) @@ -676,11 +793,10 @@ static void genmov16(uae_u32 opcode, struct instr *curi) comprintf("\tuae_u16 dstreg=((%s)>>12)&0x07;\n", gen_nextiword()); comprintf("\tmov_l_rr(src,8+srcreg);\n"); comprintf("\tmov_l_rr(dst,8+dstreg);\n"); - } - else { + } else { /* Other variants */ - genamode (curi->smode, "srcreg", curi->size, "src", 0, 2); - genamode (curi->dmode, "dstreg", curi->size, "dst", 0, 2); + genamode(curi->smode, "srcreg", curi->size, "src", GENA_GETV_NO_FETCH, GENA_MOVEM_MOVE16); + genamode(curi->dmode, "dstreg", curi->size, "dst", GENA_GETV_NO_FETCH, GENA_MOVEM_MOVE16); comprintf("\tmov_l_rr(src,srca);\n"); comprintf("\tmov_l_rr(dst,dsta);\n"); } @@ -693,8 +809,7 @@ static void genmov16(uae_u32 opcode, struct instr *curi) comprintf("\tif (srcreg != dstreg)\n"); comprintf("\tadd_l_ri(srcreg+8,16);\n"); comprintf("\tadd_l_ri(dstreg+8,16);\n"); - } - else if ((opcode & 0xfff8) == 0xf600) + } else if ((opcode & 0xfff8) == 0xf600) comprintf("\tadd_l_ri(srcreg+8,16);\n"); else if ((opcode & 0xfff8) == 0xf608) comprintf("\tadd_l_ri(dstreg+8,16);\n"); @@ -703,22 +818,23 @@ static void genmov16(uae_u32 opcode, struct instr *curi) comprintf("\tif (special_mem) {\n"); comprintf("\t\tint tmp=scratchie;\n"); comprintf("\tscratchie+=4;\n" - "\treadlong(src,tmp,scratchie);\n" - "\twritelong_clobber(dst,tmp,scratchie);\n" - "\tadd_l_ri(src,4);\n" - "\tadd_l_ri(dst,4);\n" - "\treadlong(src,tmp,scratchie);\n" - "\twritelong_clobber(dst,tmp,scratchie);\n" - "\tadd_l_ri(src,4);\n" - "\tadd_l_ri(dst,4);\n" - "\treadlong(src,tmp,scratchie);\n" - "\twritelong_clobber(dst,tmp,scratchie);\n" - "\tadd_l_ri(src,4);\n" - "\tadd_l_ri(dst,4);\n" - "\treadlong(src,tmp,scratchie);\n" - "\twritelong_clobber(dst,tmp,scratchie);\n"); - comprintf("\t} else {\n"); + "\treadlong(src,tmp,scratchie);\n" + "\twritelong_clobber(dst,tmp,scratchie);\n" + "\tadd_l_ri(src,4);\n" + "\tadd_l_ri(dst,4);\n" + "\treadlong(src,tmp,scratchie);\n" + "\twritelong_clobber(dst,tmp,scratchie);\n" + "\tadd_l_ri(src,4);\n" + "\tadd_l_ri(dst,4);\n" + "\treadlong(src,tmp,scratchie);\n" + "\twritelong_clobber(dst,tmp,scratchie);\n" + "\tadd_l_ri(src,4);\n" + "\tadd_l_ri(dst,4);\n" + "\treadlong(src,tmp,scratchie);\n" + "\twritelong_clobber(dst,tmp,scratchie);\n"); + comprintf("\t} else\n"); #endif + start_brace(); comprintf("\tint tmp=scratchie;\n"); comprintf("\tscratchie+=4;\n" "\tget_n_addr(src,src,scratchie);\n" @@ -734,2465 +850,2208 @@ static void genmov16(uae_u32 opcode, struct instr *curi) "\tmov_l_Rr(dst,tmp+2,8);\n" "\tforget_about(tmp+2);\n" "\tmov_l_Rr(dst,tmp+3,12);\n"); -#ifdef UAE - comprintf("\t}\n"); -#endif + close_brace(); } static void -genmovemel (uae_u16 opcode) +genmovemel(uae_u16 opcode) { - comprintf ("\tuae_u16 mask = %s;\n", gen_nextiword ()); - comprintf ("\tint native=scratchie++;\n"); - comprintf ("\tint i;\n"); - comprintf ("\tsigned char offset=0;\n"); - genamode (table68k[opcode].dmode, "dstreg", table68k[opcode].size, "src", 2, 1); + comprintf("\tuae_u16 mask = %s;\n", gen_nextiword()); + comprintf("\tint native=scratchie++;\n"); + comprintf("\tint i;\n"); + comprintf("\tsigned char offset=0;\n"); + genamode(table68k[opcode].dmode, "dstreg", table68k[opcode].size, "src", GENA_GETV_FETCH_ALIGN, GENA_MOVEM_NO_INC); #ifdef UAE if (table68k[opcode].size == sz_long) - comprintf("\tif (1 && !special_mem) {\n"); + comprintf("\tif (1 && !special_mem) {\n"); else - comprintf("\tif (1 && !special_mem) {\n"); + comprintf("\tif (1 && !special_mem) {\n"); #endif - /* Fast but unsafe... */ - comprintf("\tget_n_addr(srca,native,scratchie);\n"); + /* Fast but unsafe... */ + comprintf("\tget_n_addr(srca,native,scratchie);\n"); - comprintf("\tfor (i=0;i<16;i++) {\n" - "\t\tif ((mask>>i)&1) {\n"); - switch(table68k[opcode].size) { - case sz_long: - comprintf("\t\t\tmov_l_rR(i,native,offset);\n" - "\t\t\tmid_bswap_32(i);\n" - "\t\t\toffset+=4;\n"); - break; - case sz_word: - comprintf("\t\t\tmov_w_rR(i,native,offset);\n" - "\t\t\tmid_bswap_16(i);\n" - "\t\t\tsign_extend_16_rr(i,i);\n" - "\t\t\toffset+=2;\n"); - break; - default: assert(0); - } - comprintf("\t\t}\n" - "\t}"); - if (table68k[opcode].dmode == Aipi) { - comprintf("\t\t\tlea_l_brr(8+dstreg,srca,offset);\n"); - } - /* End fast but unsafe. */ + comprintf("\tfor (i=0;i<16;i++) {\n" + "\t\tif ((mask>>i)&1) {\n"); + switch (table68k[opcode].size) { + case sz_long: + comprintf("\t\t\tmov_l_rR(i,native,offset);\n" + "\t\t\tmid_bswap_32(i);\n" + "\t\t\toffset+=4;\n"); + break; + case sz_word: + comprintf("\t\t\tmov_w_rR(i,native,offset);\n" + "\t\t\tmid_bswap_16(i);\n" + "\t\t\tsign_extend_16_rr(i,i);\n" + "\t\t\toffset+=2;\n"); + break; + default: assert(0); + } + comprintf("\t\t}\n" + "\t}"); + if (table68k[opcode].dmode == Aipi) { + comprintf("\t\t\tlea_l_brr(8+dstreg,srca,offset);\n"); + } + /* End fast but unsafe. */ #ifdef UAE - comprintf("\t} else {\n"); + comprintf("\t} else {\n"); - comprintf ("\t\tint tmp=scratchie++;\n"); + comprintf("\t\tint tmp=scratchie++;\n"); - comprintf("\t\tmov_l_rr(tmp,srca);\n"); - comprintf("\t\tfor (i=0;i<16;i++) {\n" - "\t\t\tif ((mask>>i)&1) {\n"); - switch(table68k[opcode].size) { - case sz_long: - comprintf("\t\t\t\treadlong(tmp,i,scratchie);\n" - "\t\t\t\tadd_l_ri(tmp,4);\n"); - break; - case sz_word: - comprintf("\t\t\t\treadword(tmp,i,scratchie);\n" - "\t\t\t\tadd_l_ri(tmp,2);\n"); - break; - default: assert(0); - } + comprintf("\t\tmov_l_rr(tmp,srca);\n"); + comprintf("\t\tfor (i=0;i<16;i++) {\n" + "\t\t\tif ((mask>>i)&1) {\n"); + switch (table68k[opcode].size) { + case sz_long: + comprintf("\t\t\t\treadlong(tmp,i,scratchie);\n" + "\t\t\t\tadd_l_ri(tmp,4);\n"); + break; + case sz_word: + comprintf("\t\t\t\treadword(tmp,i,scratchie);\n" + "\t\t\t\tadd_l_ri(tmp,2);\n"); + break; + default: assert(0); + } - comprintf("\t\t\t}\n" - "\t\t}\n"); - if (table68k[opcode].dmode == Aipi) { - comprintf("\t\tmov_l_rr(8+dstreg,tmp);\n"); - } - comprintf("\t}\n"); + comprintf("\t\t\t}\n" + "\t\t}\n"); + if (table68k[opcode].dmode == Aipi) { + comprintf("\t\tmov_l_rr(8+dstreg,tmp);\n"); + } + comprintf("\t}\n"); #endif } static void -genmovemle (uae_u16 opcode) +genmovemle(uae_u16 opcode) { - comprintf ("\tuae_u16 mask = %s;\n", gen_nextiword ()); - comprintf ("\tint native=scratchie++;\n"); - comprintf ("\tint i;\n"); - comprintf ("\tint tmp=scratchie++;\n"); - comprintf ("\tsigned char offset=0;\n"); - genamode (table68k[opcode].dmode, "dstreg", table68k[opcode].size, "src", 2, 1); + comprintf("\tuae_u16 mask = %s;\n", gen_nextiword()); + comprintf("\tint native=scratchie++;\n"); + comprintf("\tint i;\n"); + comprintf("\tint tmp=scratchie++;\n"); + comprintf("\tsigned char offset=0;\n"); + genamode(table68k[opcode].dmode, "dstreg", table68k[opcode].size, "src", GENA_GETV_FETCH_ALIGN, GENA_MOVEM_NO_INC); #ifdef UAE - /* *Sigh* Some clever geek realized that the fastest way to copy a - buffer from main memory to the gfx card is by using movmle. Good - on her, but unfortunately, gfx mem isn't "real" mem, and thus that - act of cleverness means that movmle must pay attention to special_mem, - or Genetic Species is a rather boring-looking game ;-) */ + /* *Sigh* Some clever geek realized that the fastest way to copy a + buffer from main memory to the gfx card is by using movmle. Good + on her, but unfortunately, gfx mem isn't "real" mem, and thus that + act of cleverness means that movmle must pay attention to special_mem, + or Genetic Species is a rather boring-looking game ;-) */ if (table68k[opcode].size == sz_long) - comprintf("\tif (1 && !special_mem) {\n"); + comprintf("\tif (1 && !special_mem) {\n"); else - comprintf("\tif (1 && !special_mem) {\n"); + comprintf("\tif (1 && !special_mem) {\n"); #endif - comprintf("\tget_n_addr(srca,native,scratchie);\n"); + comprintf("\tget_n_addr(srca,native,scratchie);\n"); - if (table68k[opcode].dmode!=Apdi) { - comprintf("\tfor (i=0;i<16;i++) {\n" - "\t\tif ((mask>>i)&1) {\n"); - switch(table68k[opcode].size) { - case sz_long: - comprintf("\t\t\tmov_l_rr(tmp,i);\n" - "\t\t\tmid_bswap_32(tmp);\n" - "\t\t\tmov_l_Rr(native,tmp,offset);\n" - "\t\t\toffset+=4;\n"); - break; - case sz_word: - comprintf("\t\t\tmov_l_rr(tmp,i);\n" - "\t\t\tmid_bswap_16(tmp);\n" - "\t\t\tmov_w_Rr(native,tmp,offset);\n" - "\t\t\toffset+=2;\n"); - break; - default: assert(0); - } - } - else { /* Pre-decrement */ - comprintf("\tfor (i=0;i<16;i++) {\n" - "\t\tif ((mask>>i)&1) {\n"); - switch(table68k[opcode].size) { - case sz_long: - comprintf("\t\t\toffset-=4;\n" - "\t\t\tmov_l_rr(tmp,15-i);\n" - "\t\t\tmid_bswap_32(tmp);\n" - "\t\t\tmov_l_Rr(native,tmp,offset);\n" - ); - break; - case sz_word: - comprintf("\t\t\toffset-=2;\n" - "\t\t\tmov_l_rr(tmp,15-i);\n" - "\t\t\tmid_bswap_16(tmp);\n" - "\t\t\tmov_w_Rr(native,tmp,offset);\n" - ); - break; - default: assert(0); + if (table68k[opcode].dmode != Apdi) { + comprintf("\tfor (i=0;i<16;i++) {\n" + "\t\tif ((mask>>i)&1) {\n"); + switch (table68k[opcode].size) { + case sz_long: + comprintf("\t\t\tmov_l_rr(tmp,i);\n" + "\t\t\tmid_bswap_32(tmp);\n" + "\t\t\tmov_l_Rr(native,tmp,offset);\n" + "\t\t\toffset+=4;\n"); + break; + case sz_word: + comprintf("\t\t\tmov_l_rr(tmp,i);\n" + "\t\t\tmid_bswap_16(tmp);\n" + "\t\t\tmov_w_Rr(native,tmp,offset);\n" + "\t\t\toffset+=2;\n"); + break; + default: assert(0); + } + } else { /* Pre-decrement */ + comprintf("\tfor (i=0;i<16;i++) {\n" + "\t\tif ((mask>>i)&1) {\n"); + switch (table68k[opcode].size) { + case sz_long: + comprintf("\t\t\toffset-=4;\n" + "\t\t\tmov_l_rr(tmp,15-i);\n" + "\t\t\tmid_bswap_32(tmp);\n" + "\t\t\tmov_l_Rr(native,tmp,offset);\n" + ); + break; + case sz_word: + comprintf("\t\t\toffset-=2;\n" + "\t\t\tmov_l_rr(tmp,15-i);\n" + "\t\t\tmid_bswap_16(tmp);\n" + "\t\t\tmov_w_Rr(native,tmp,offset);\n" + ); + break; + default: assert(0); + } } - } - comprintf("\t\t}\n" - "\t}"); - if (table68k[opcode].dmode == Apdi) { - comprintf("\t\t\tlea_l_brr(8+dstreg,srca,(uae_s32)offset);\n"); - } + comprintf("\t\t}\n" + "\t}"); + if (table68k[opcode].dmode == Apdi) { + comprintf("\t\t\tlea_l_brr(8+dstreg,srca,(uae_s32)offset);\n"); + } #ifdef UAE - comprintf("\t} else {\n"); + comprintf("\t} else {\n"); - if (table68k[opcode].dmode!=Apdi) { - comprintf("\tmov_l_rr(tmp,srca);\n"); - comprintf("\tfor (i=0;i<16;i++) {\n" - "\t\tif ((mask>>i)&1) {\n"); - switch(table68k[opcode].size) { - case sz_long: - comprintf("\t\t\twritelong(tmp,i,scratchie);\n" - "\t\t\tadd_l_ri(tmp,4);\n"); - break; - case sz_word: - comprintf("\t\t\twriteword(tmp,i,scratchie);\n" - "\t\t\tadd_l_ri(tmp,2);\n"); - break; - default: assert(0); - } - } - else { /* Pre-decrement */ - comprintf("\tfor (i=0;i<16;i++) {\n" - "\t\tif ((mask>>i)&1) {\n"); - switch(table68k[opcode].size) { - case sz_long: - comprintf("\t\t\tsub_l_ri(srca,4);\n" - "\t\t\twritelong(srca,15-i,scratchie);\n"); - break; - case sz_word: - comprintf("\t\t\tsub_l_ri(srca,2);\n" - "\t\t\twriteword(srca,15-i,scratchie);\n"); - break; - default: assert(0); + if (table68k[opcode].dmode != Apdi) { + comprintf("\tmov_l_rr(tmp,srca);\n"); + comprintf("\tfor (i=0;i<16;i++) {\n" + "\t\tif ((mask>>i)&1) {\n"); + switch (table68k[opcode].size) { + case sz_long: + comprintf("\t\t\twritelong(tmp,i,scratchie);\n" + "\t\t\tadd_l_ri(tmp,4);\n"); + break; + case sz_word: + comprintf("\t\t\twriteword(tmp,i,scratchie);\n" + "\t\t\tadd_l_ri(tmp,2);\n"); + break; + default: assert(0); + } + } else { /* Pre-decrement */ + comprintf("\tfor (i=0;i<16;i++) {\n" + "\t\tif ((mask>>i)&1) {\n"); + switch (table68k[opcode].size) { + case sz_long: + comprintf("\t\t\tsub_l_ri(srca,4);\n" + "\t\t\twritelong(srca,15-i,scratchie);\n"); + break; + case sz_word: + comprintf("\t\t\tsub_l_ri(srca,2);\n" + "\t\t\twriteword(srca,15-i,scratchie);\n"); + break; + default: assert(0); + } } - } - comprintf("\t\t}\n" - "\t}"); - if (table68k[opcode].dmode == Apdi) { - comprintf("\t\t\tmov_l_rr(8+dstreg,srca);\n"); - } - comprintf("\t}\n"); + comprintf("\t\t}\n" + "\t}"); + if (table68k[opcode].dmode == Apdi) { + comprintf("\t\t\tmov_l_rr(8+dstreg,srca);\n"); + } + comprintf("\t}\n"); #endif } static void -duplicate_carry (void) +duplicate_carry(void) { - comprintf ("\tif (needed_flags&FLAG_X) duplicate_carry();\n"); + comprintf("\tif (needed_flags&FLAG_X) duplicate_carry();\n"); } typedef enum { - flag_logical_noclobber, flag_logical, flag_add, flag_sub, flag_cmp, - flag_addx, flag_subx, flag_zn, flag_av, flag_sv, flag_and, flag_or, - flag_eor, flag_mov + flag_logical_noclobber, flag_logical, flag_add, flag_sub, flag_cmp, + flag_addx, flag_subx, flag_zn, flag_av, flag_sv, flag_and, flag_or, + flag_eor, flag_mov } flagtypes; static void -genflags (flagtypes type, wordsizes size, const char *value, const char *src, const char *dst) +genflags(flagtypes type, wordsizes size, const char *value, const char *src, const char *dst) { - if (noflags) { - switch(type) { - case flag_cmp: - comprintf("\tdont_care_flags();\n"); - comprintf("/* Weird --- CMP with noflags ;-) */\n"); - return; - case flag_add: - case flag_sub: - comprintf("\tdont_care_flags();\n"); - { - const char* op; - switch(type) { - case flag_add: op="add"; break; - case flag_sub: op="sub"; break; - default: assert(0); + if (noflags) { + switch (type) { + case flag_cmp: + comprintf("\tdont_care_flags();\n"); + comprintf("/* Weird --- CMP with noflags ;-) */\n"); + return; + case flag_add: + case flag_sub: + comprintf("\tdont_care_flags();\n"); + { + const char *op; + switch (type) { + case flag_add: op = "add"; break; + case flag_sub: op = "sub"; break; + default: assert(0); + } + switch (size) + { + case sz_byte: + comprintf("\t%s_b(%s,%s);\n", op, dst, src); + break; + case sz_word: + comprintf("\t%s_w(%s,%s);\n", op, dst, src); + break; + case sz_long: + comprintf("\t%s_l(%s,%s);\n", op, dst, src); + break; + } + return; + } + break; + + case flag_and: + comprintf("\tdont_care_flags();\n"); + switch (size) + { + case sz_byte: + comprintf("if (kill_rodent(dst)) {\n"); + comprintf("\tzero_extend_8_rr(scratchie,%s);\n", src); + comprintf("\tor_l_ri(scratchie,0xffffff00);\n"); + comprintf("\tand_l(%s,scratchie);\n", dst); + comprintf("\tforget_about(scratchie);\n"); + comprintf("\t} else \n" + "\tand_b(%s,%s);\n", dst, src); + break; + case sz_word: + comprintf("if (kill_rodent(dst)) {\n"); + comprintf("\tzero_extend_16_rr(scratchie,%s);\n", src); + comprintf("\tor_l_ri(scratchie,0xffff0000);\n"); + comprintf("\tand_l(%s,scratchie);\n", dst); + comprintf("\tforget_about(scratchie);\n"); + comprintf("\t} else \n" + "\tand_w(%s,%s);\n", dst, src); + break; + case sz_long: + comprintf("\tand_l(%s,%s);\n", dst, src); + break; + } + return; + + case flag_mov: + comprintf("\tdont_care_flags();\n"); + switch (size) + { + case sz_byte: + comprintf("if (kill_rodent(dst)) {\n"); + comprintf("\tzero_extend_8_rr(scratchie,%s);\n", src); + comprintf("\tand_l_ri(%s,0xffffff00);\n", dst); + comprintf("\tor_l(%s,scratchie);\n", dst); + comprintf("\tforget_about(scratchie);\n"); + comprintf("\t} else \n" + "\tmov_b_rr(%s,%s);\n", dst, src); + break; + case sz_word: + comprintf("if (kill_rodent(dst)) {\n"); + comprintf("\tzero_extend_16_rr(scratchie,%s);\n", src); + comprintf("\tand_l_ri(%s,0xffff0000);\n", dst); + comprintf("\tor_l(%s,scratchie);\n", dst); + comprintf("\tforget_about(scratchie);\n"); + comprintf("\t} else \n" + "\tmov_w_rr(%s,%s);\n", dst, src); + break; + case sz_long: + comprintf("\tmov_l_rr(%s,%s);\n", dst, src); + break; + } + return; + + case flag_or: + case flag_eor: + comprintf("\tdont_care_flags();\n"); + start_brace(); + { + const char *op; + switch (type) { + case flag_or: op = "or"; break; + case flag_eor: op = "xor"; break; + default: assert(0); + } + switch (size) + { + case sz_byte: + comprintf("if (kill_rodent(dst)) {\n"); + comprintf("\tzero_extend_8_rr(scratchie,%s);\n", src); + comprintf("\t%s_l(%s,scratchie);\n", op, dst); + comprintf("\tforget_about(scratchie);\n"); + comprintf("\t} else \n" + "\t%s_b(%s,%s);\n", op, dst, src); + break; + case sz_word: + comprintf("if (kill_rodent(dst)) {\n"); + comprintf("\tzero_extend_16_rr(scratchie,%s);\n", src); + comprintf("\t%s_l(%s,scratchie);\n", op, dst); + comprintf("\tforget_about(scratchie);\n"); + comprintf("\t} else \n" + "\t%s_w(%s,%s);\n", op, dst, src); + break; + case sz_long: + comprintf("\t%s_l(%s,%s);\n", op, dst, src); + break; + } + close_brace(); + return; + } + + + case flag_addx: + case flag_subx: + comprintf("\tdont_care_flags();\n"); + { + const char *op; + switch (type) { + case flag_addx: op = "adc"; break; + case flag_subx: op = "sbb"; break; + default: assert(0); + } + comprintf("\trestore_carry();\n"); /* Reload the X flag into C */ + switch (size) + { + case sz_byte: + comprintf("\t%s_b(%s,%s);\n", op, dst, src); + break; + case sz_word: + comprintf("\t%s_w(%s,%s);\n", op, dst, src); + break; + case sz_long: + comprintf("\t%s_l(%s,%s);\n", op, dst, src); + break; + } + return; + } + break; + default: return; } - switch (size) + } + + /* Need the flags, but possibly not all of them */ + switch (type) + { + case flag_logical_noclobber: + failure; + /* fall through */ + + case flag_and: + case flag_or: + case flag_eor: + comprintf("\tdont_care_flags();\n"); + start_brace(); { - case sz_byte: - comprintf("\t%s_b(%s,%s);\n",op,dst,src); - break; - case sz_word: - comprintf("\t%s_w(%s,%s);\n",op,dst,src); - break; - case sz_long: - comprintf("\t%s_l(%s,%s);\n",op,dst,src); - break; + const char *op; + switch (type) { + case flag_and: op = "and"; break; + case flag_or: op = "or"; break; + case flag_eor: op = "xor"; break; + default: assert(0); + } + switch (size) + { + case sz_byte: + comprintf("\tstart_needflags();\n" + "\t%s_b(%s,%s);\n", op, dst, src); + break; + case sz_word: + comprintf("\tstart_needflags();\n" + "\t%s_w(%s,%s);\n", op, dst, src); + break; + case sz_long: + comprintf("\tstart_needflags();\n" + "\t%s_l(%s,%s);\n", op, dst, src); + break; + } + comprintf("\tlive_flags();\n"); + comprintf("\tend_needflags();\n"); + close_brace(); + return; } - return; - } - break; - - case flag_and: - comprintf("\tdont_care_flags();\n"); - switch (size) - { - case sz_byte: - comprintf("if (kill_rodent(dst)) {\n"); - comprintf("\tzero_extend_8_rr(scratchie,%s);\n",src); - comprintf("\tor_l_ri(scratchie,0xffffff00);\n"); - comprintf("\tand_l(%s,scratchie);\n",dst); - comprintf("\tforget_about(scratchie);\n"); - comprintf("\t} else \n" - "\tand_b(%s,%s);\n",dst,src); - break; - case sz_word: - comprintf("if (kill_rodent(dst)) {\n"); - comprintf("\tzero_extend_16_rr(scratchie,%s);\n",src); - comprintf("\tor_l_ri(scratchie,0xffff0000);\n"); - comprintf("\tand_l(%s,scratchie);\n",dst); - comprintf("\tforget_about(scratchie);\n"); - comprintf("\t} else \n" - "\tand_w(%s,%s);\n",dst,src); - break; - case sz_long: - comprintf("\tand_l(%s,%s);\n",dst,src); - break; - } - return; - - case flag_mov: - comprintf("\tdont_care_flags();\n"); - switch (size) - { - case sz_byte: - comprintf("if (kill_rodent(dst)) {\n"); - comprintf("\tzero_extend_8_rr(scratchie,%s);\n",src); - comprintf("\tand_l_ri(%s,0xffffff00);\n",dst); - comprintf("\tor_l(%s,scratchie);\n",dst); - comprintf("\tforget_about(scratchie);\n"); - comprintf("\t} else \n" - "\tmov_b_rr(%s,%s);\n",dst,src); - break; - case sz_word: - comprintf("if (kill_rodent(dst)) {\n"); - comprintf("\tzero_extend_16_rr(scratchie,%s);\n",src); - comprintf("\tand_l_ri(%s,0xffff0000);\n",dst); - comprintf("\tor_l(%s,scratchie);\n",dst); - comprintf("\tforget_about(scratchie);\n"); - comprintf("\t} else \n" - "\tmov_w_rr(%s,%s);\n",dst,src); - break; - case sz_long: - comprintf("\tmov_l_rr(%s,%s);\n",dst,src); - break; - } - return; - - case flag_or: - case flag_eor: - comprintf("\tdont_care_flags();\n"); - start_brace(); - { - const char* op; - switch(type) { - case flag_or: op="or"; break; - case flag_eor: op="xor"; break; - default: assert(0); + + case flag_mov: + comprintf("\tdont_care_flags();\n"); + start_brace(); + { + switch (size) + { + case sz_byte: + comprintf("\tif (%s!=%s) {\n", src, dst); + comprintf("\tmov_b_ri(%s,0);\n" + "\tstart_needflags();\n", dst); + comprintf("\tor_b(%s,%s);\n", dst, src); + comprintf("\t} else {\n"); + comprintf("\tmov_b_rr(%s,%s);\n", dst, src); + comprintf("\ttest_b_rr(%s,%s);\n", dst, dst); + comprintf("\t}\n"); + break; + case sz_word: + comprintf("\tif (%s!=%s) {\n", src, dst); + comprintf("\tmov_w_ri(%s,0);\n" + "\tstart_needflags();\n", dst); + comprintf("\tor_w(%s,%s);\n", dst, src); + comprintf("\t} else {\n"); + comprintf("\tmov_w_rr(%s,%s);\n", dst, src); + comprintf("\ttest_w_rr(%s,%s);\n", dst, dst); + comprintf("\t}\n"); + break; + case sz_long: + comprintf("\tif (%s!=%s) {\n", src, dst); + comprintf("\tmov_l_ri(%s,0);\n" + "\tstart_needflags();\n", dst); + comprintf("\tor_l(%s,%s);\n", dst, src); + comprintf("\t} else {\n"); + comprintf("\tmov_l_rr(%s,%s);\n", dst, src); + comprintf("\ttest_l_rr(%s,%s);\n", dst, dst); + comprintf("\t}\n"); + break; + } + comprintf("\tlive_flags();\n"); + comprintf("\tend_needflags();\n"); + close_brace(); + return; } + + case flag_logical: + comprintf("\tdont_care_flags();\n"); + start_brace(); switch (size) { - case sz_byte: - comprintf("if (kill_rodent(dst)) {\n"); - comprintf("\tzero_extend_8_rr(scratchie,%s);\n",src); - comprintf("\t%s_l(%s,scratchie);\n",op,dst); - comprintf("\tforget_about(scratchie);\n"); - comprintf("\t} else \n" - "\t%s_b(%s,%s);\n",op,dst,src); - break; - case sz_word: - comprintf("if (kill_rodent(dst)) {\n"); - comprintf("\tzero_extend_16_rr(scratchie,%s);\n",src); - comprintf("\t%s_l(%s,scratchie);\n",op,dst); - comprintf("\tforget_about(scratchie);\n"); - comprintf("\t} else \n" - "\t%s_w(%s,%s);\n",op,dst,src); - break; - case sz_long: - comprintf("\t%s_l(%s,%s);\n",op,dst,src); - break; + case sz_byte: + comprintf("\tstart_needflags();\n" + "\ttest_b_rr(%s,%s);\n", value, value); + break; + case sz_word: + comprintf("\tstart_needflags();\n" + "\ttest_w_rr(%s,%s);\n", value, value); + break; + case sz_long: + comprintf("\tstart_needflags();\n" + "\ttest_l_rr(%s,%s);\n", value, value); + break; } + comprintf("\tlive_flags();\n"); + comprintf("\tend_needflags();\n"); close_brace(); return; - } - case flag_addx: - case flag_subx: - comprintf("\tdont_care_flags();\n"); - { - const char* op; - switch(type) { - case flag_addx: op="adc"; break; - case flag_subx: op="sbb"; break; - default: assert(0); + case flag_add: + case flag_sub: + case flag_cmp: + comprintf("\tdont_care_flags();\n"); + { + const char *op; + switch (type) { + case flag_add: op = "add"; break; + case flag_sub: op = "sub"; break; + case flag_cmp: op = "cmp"; break; + default: assert(0); + } + switch (size) + { + case sz_byte: + comprintf("\tstart_needflags();\n" + "\t%s_b(%s,%s);\n", op, dst, src); + break; + case sz_word: + comprintf("\tstart_needflags();\n" + "\t%s_w(%s,%s);\n", op, dst, src); + break; + case sz_long: + comprintf("\tstart_needflags();\n" + "\t%s_l(%s,%s);\n", op, dst, src); + break; + } + comprintf("\tlive_flags();\n"); + comprintf("\tend_needflags();\n"); + if (type != flag_cmp) { + duplicate_carry(); + } + comprintf("if (!(needed_flags & FLAG_CZNV)) dont_care_flags();\n"); + + return; } - comprintf("\trestore_carry();\n"); /* Reload the X flag into C */ - switch (size) + + case flag_addx: + case flag_subx: + uses_cmov; + comprintf("\tdont_care_flags();\n"); { - case sz_byte: - comprintf("\t%s_b(%s,%s);\n",op,dst,src); - break; - case sz_word: - comprintf("\t%s_w(%s,%s);\n",op,dst,src); - break; - case sz_long: - comprintf("\t%s_l(%s,%s);\n",op,dst,src); - break; + const char *op; + switch (type) { + case flag_addx: op = "adc"; break; + case flag_subx: op = "sbb"; break; + default: assert(0); + } + start_brace(); + comprintf("\tint zero=scratchie++;\n" + "\tint one=scratchie++;\n" + "\tif (needed_flags&FLAG_Z) {\n" + "\tmov_l_ri(zero,0);\n" + "\tmov_l_ri(one,-1);\n" + "\tmake_flags_live();\n" + "\tcmov_l_rr(zero,one,%d);\n" + "\t}\n", NATIVE_CC_NE); + comprintf("\trestore_carry();\n"); /* Reload the X flag into C */ + switch (size) + { + case sz_byte: + comprintf("\tstart_needflags();\n" + "\t%s_b(%s,%s);\n", op, dst, src); + break; + case sz_word: + comprintf("\tstart_needflags();\n" + "\t%s_w(%s,%s);\n", op, dst, src); + break; + case sz_long: + comprintf("\tstart_needflags();\n" + "\t%s_l(%s,%s);\n", op, dst, src); + break; + } + comprintf("\tlive_flags();\n"); + comprintf("\tif (needed_flags&FLAG_Z) {\n"); + comprintf("\tcmov_l_rr(zero,one,%d);\n", NATIVE_CC_NE); + comprintf("\tset_zero(zero, one);\n"); /* No longer need one */ + comprintf("\tlive_flags();\n"); + comprintf("\t}\n"); + comprintf("\tend_needflags();\n"); + duplicate_carry(); + comprintf("if (!(needed_flags & FLAG_CZNV)) dont_care_flags();\n"); + return; } - return; - } - break; - default: return; - } - } - - /* Need the flags, but possibly not all of them */ - switch (type) - { - case flag_logical_noclobber: - failure; - - case flag_and: - case flag_or: - case flag_eor: - comprintf("\tdont_care_flags();\n"); - start_brace(); - { - const char* op; - switch(type) { - case flag_and: op="and"; break; - case flag_or: op="or"; break; - case flag_eor: op="xor"; break; - default: assert(0); - } - switch (size) - { - case sz_byte: - comprintf("\tstart_needflags();\n" - "\t%s_b(%s,%s);\n",op,dst,src); - break; - case sz_word: - comprintf("\tstart_needflags();\n" - "\t%s_w(%s,%s);\n",op,dst,src); - break; - case sz_long: - comprintf("\tstart_needflags();\n" - "\t%s_l(%s,%s);\n",op,dst,src); - break; - } - comprintf("\tlive_flags();\n"); - comprintf("\tend_needflags();\n"); - close_brace(); - return; + default: + failure; + break; } +} - case flag_mov: - comprintf("\tdont_care_flags();\n"); - start_brace(); - { - switch (size) - { - case sz_byte: - comprintf("\tif (%s!=%s) {\n",src,dst); - comprintf("\tmov_b_ri(%s,0);\n" - "\tstart_needflags();\n",dst); - comprintf("\tor_b(%s,%s);\n",dst,src); - comprintf("\t} else {\n"); - comprintf("\tmov_b_rr(%s,%s);\n",dst,src); - comprintf("\ttest_b_rr(%s,%s);\n",dst,dst); - comprintf("\t}\n"); - break; - case sz_word: - comprintf("\tif (%s!=%s) {\n",src,dst); - comprintf("\tmov_w_ri(%s,0);\n" - "\tstart_needflags();\n",dst); - comprintf("\tor_w(%s,%s);\n",dst,src); - comprintf("\t} else {\n"); - comprintf("\tmov_w_rr(%s,%s);\n",dst,src); - comprintf("\ttest_w_rr(%s,%s);\n",dst,dst); - comprintf("\t}\n"); - break; - case sz_long: - comprintf("\tif (%s!=%s) {\n",src,dst); - comprintf("\tmov_l_ri(%s,0);\n" - "\tstart_needflags();\n",dst); - comprintf("\tor_l(%s,%s);\n",dst,src); - comprintf("\t} else {\n"); - comprintf("\tmov_l_rr(%s,%s);\n",dst,src); - comprintf("\ttest_l_rr(%s,%s);\n",dst,dst); - comprintf("\t}\n"); - break; - } - comprintf("\tlive_flags();\n"); - comprintf("\tend_needflags();\n"); - close_brace(); - return; - } +static int /* returns zero for success, non-zero for failure */ +gen_opcode(unsigned int opcode) +{ + struct instr *curi = table68k + opcode; + const char *ssize = NULL; + + insn_n_cycles = 2; + global_failure = 0; + long_opcode = 0; + global_isjump = 0; + global_iscjump = 0; + global_isaddx = 0; + global_cmov = 0; + global_fpu = 0; + global_mayfail = 0; + hack_opcode = opcode; + endstr[0] = 0; - case flag_logical: - comprintf("\tdont_care_flags();\n"); start_brace(); - switch (size) + comprintf("\tuae_u8 scratchie=S1;\n"); + switch (curi->plev) { - case sz_byte: - comprintf("\tstart_needflags();\n" - "\ttest_b_rr(%s,%s);\n",value,value); - break; - case sz_word: - comprintf("\tstart_needflags();\n" - "\ttest_w_rr(%s,%s);\n",value,value); - break; - case sz_long: - comprintf("\tstart_needflags();\n" - "\ttest_l_rr(%s,%s);\n",value,value); - break; - } - comprintf("\tlive_flags();\n"); - comprintf("\tend_needflags();\n"); - close_brace(); - return; - + case 0: /* not privileged */ + break; + case 1: /* unprivileged only on 68000 */ + if (cpu_level == 0) + break; + if (next_cpu_level < 0) + next_cpu_level = 0; - case flag_add: - case flag_sub: - case flag_cmp: - comprintf("\tdont_care_flags();\n"); - { - const char* op; - switch(type) { - case flag_add: op="add"; break; - case flag_sub: op="sub"; break; - case flag_cmp: op="cmp"; break; - default: assert(0); - } - switch (size) - { - case sz_byte: - comprintf("\tstart_needflags();\n" - "\t%s_b(%s,%s);\n",op,dst,src); - break; - case sz_word: - comprintf("\tstart_needflags();\n" - "\t%s_w(%s,%s);\n",op,dst,src); - break; - case sz_long: - comprintf("\tstart_needflags();\n" - "\t%s_l(%s,%s);\n",op,dst,src); - break; - } - comprintf("\tlive_flags();\n"); - comprintf("\tend_needflags();\n"); - if (type!=flag_cmp) { - duplicate_carry(); - } - comprintf("if (!(needed_flags & FLAG_CZNV)) dont_care_flags();\n"); - - return; + /* fall through */ + case 2: /* priviledged */ + failure; /* Easy ones first */ + break; + case 3: /* privileged if size == word */ + if (curi->size == sz_byte) + break; + failure; + break; } - - case flag_addx: - case flag_subx: - uses_cmov; - comprintf("\tdont_care_flags();\n"); - { - const char* op; - switch(type) { - case flag_addx: op="adc"; break; - case flag_subx: op="sbb"; break; - default: assert(0); - } - start_brace(); - comprintf("\tint zero=scratchie++;\n" - "\tint one=scratchie++;\n" - "\tif (needed_flags&FLAG_Z) {\n" - "\tmov_l_ri(zero,0);\n" - "\tmov_l_ri(one,-1);\n" - "\tmake_flags_live();\n" - "\tcmov_l_rr(zero,one,%d);\n" - "\t}\n",NATIVE_CC_NE); - comprintf("\trestore_carry();\n"); /* Reload the X flag into C */ - switch (size) - { - case sz_byte: - comprintf("\tstart_needflags();\n" - "\t%s_b(%s,%s);\n",op,dst,src); - break; - case sz_word: - comprintf("\tstart_needflags();\n" - "\t%s_w(%s,%s);\n",op,dst,src); - break; - case sz_long: - comprintf("\tstart_needflags();\n" - "\t%s_l(%s,%s);\n",op,dst,src); - break; - } - comprintf("\tlive_flags();\n"); - comprintf("\tif (needed_flags&FLAG_Z) {\n"); - comprintf("\tcmov_l_rr(zero,one,%d);\n", NATIVE_CC_NE); - comprintf("\tset_zero(zero, one);\n"); /* No longer need one */ - comprintf("\tlive_flags();\n"); - comprintf("\t}\n"); - comprintf("\tend_needflags();\n"); - duplicate_carry(); - comprintf("if (!(needed_flags & FLAG_CZNV)) dont_care_flags();\n"); - return; + switch (curi->size) { + case sz_byte: ssize = "b"; break; + case sz_word: ssize = "w"; break; + case sz_long: ssize = "l"; break; + default: assert(0); } - default: - failure; - break; - } -} + (void)ssize; -static int /* returns zero for success, non-zero for failure */ -gen_opcode (unsigned int opcode) -{ - struct instr *curi = table68k + opcode; - const char* ssize=NULL; - - insn_n_cycles = 2; - global_failure=0; - long_opcode=0; - global_isjump=0; - global_iscjump=0; - global_isaddx=0; - global_cmov=0; - global_fpu=0; - global_mayfail=0; - hack_opcode=opcode; - endstr[0]=0; - - start_brace (); - comprintf("\tuae_u8 scratchie=S1;\n"); - switch (curi->plev) - { - case 0: /* not privileged */ - break; - case 1: /* unprivileged only on 68000 */ - if (cpu_level == 0) - break; - if (next_cpu_level < 0) - next_cpu_level = 0; - - /* fall through */ - case 2: /* priviledged */ - failure; /* Easy ones first */ - break; - case 3: /* privileged if size == word */ - if (curi->size == sz_byte) - break; - failure; - break; - } - switch (curi->size) { - case sz_byte: ssize="b"; break; - case sz_word: ssize="w"; break; - case sz_long: ssize="l"; break; - default: assert(0); - } - (void)ssize; - - switch (curi->mnemo) - { - case i_OR: - case i_AND: - case i_EOR: + switch (curi->mnemo) + { + case i_OR: + case i_AND: + case i_EOR: #ifdef DISABLE_I_OR_AND_EOR - failure; -#endif - genamode (curi->smode, "srcreg", curi->size, "src", 1, 0); - genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0); - switch(curi->mnemo) { - case i_OR: genflags (flag_or, curi->size, "", "src", "dst"); break; - case i_AND: genflags (flag_and, curi->size, "", "src", "dst"); break; - case i_EOR: genflags (flag_eor, curi->size, "", "src", "dst"); break; - } - genastore ("dst", curi->dmode, "dstreg", curi->size, "dst"); - break; + failure; +#endif + genamode(curi->smode, "srcreg", curi->size, "src", GENA_GETV_FETCH, GENA_MOVEM_DO_INC); + genamode(curi->dmode, "dstreg", curi->size, "dst", GENA_GETV_FETCH, GENA_MOVEM_DO_INC); + switch (curi->mnemo) { + case i_OR: genflags(flag_or, curi->size, "", "src", "dst"); break; + case i_AND: genflags(flag_and, curi->size, "", "src", "dst"); break; + case i_EOR: genflags(flag_eor, curi->size, "", "src", "dst"); break; + } + genastore("dst", curi->dmode, "dstreg", curi->size, "dst"); + break; - case i_ORSR: - case i_EORSR: - failure; - isjump; - break; + case i_ORSR: + case i_EORSR: + failure; + isjump; + break; - case i_ANDSR: - failure; - isjump; - break; + case i_ANDSR: + failure; + isjump; + break; - case i_SUB: + case i_SUB: #ifdef DISABLE_I_SUB - failure; + failure; #endif - genamode (curi->smode, "srcreg", curi->size, "src", 1, 0); - genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0); - genflags (flag_sub, curi->size, "", "src", "dst"); - genastore ("dst", curi->dmode, "dstreg", curi->size, "dst"); - break; + genamode(curi->smode, "srcreg", curi->size, "src", GENA_GETV_FETCH, GENA_MOVEM_DO_INC); + genamode(curi->dmode, "dstreg", curi->size, "dst", GENA_GETV_FETCH, GENA_MOVEM_DO_INC); + genflags(flag_sub, curi->size, "", "src", "dst"); + genastore("dst", curi->dmode, "dstreg", curi->size, "dst"); + break; - case i_SUBA: + case i_SUBA: #ifdef DISABLE_I_SUBA - failure; + failure; #endif - genamode (curi->smode, "srcreg", curi->size, "src", 1, 0); - genamode (curi->dmode, "dstreg", sz_long, "dst", 1, 0); - start_brace(); - comprintf("\tint tmp=scratchie++;\n"); - switch(curi->size) { - case sz_byte: comprintf("\tsign_extend_8_rr(tmp,src);\n"); break; - case sz_word: comprintf("\tsign_extend_16_rr(tmp,src);\n"); break; - case sz_long: comprintf("\ttmp=src;\n"); break; - default: assert(0); - } - comprintf("\tsub_l(dst,tmp);\n"); - genastore ("dst", curi->dmode, "dstreg", sz_long, "dst"); - break; + genamode(curi->smode, "srcreg", curi->size, "src", GENA_GETV_FETCH, GENA_MOVEM_DO_INC); + genamode(curi->dmode, "dstreg", sz_long, "dst", GENA_GETV_FETCH, GENA_MOVEM_DO_INC); + start_brace(); + comprintf("\tint tmp=scratchie++;\n"); + switch (curi->size) { + case sz_byte: comprintf("\tsign_extend_8_rr(tmp,src);\n"); break; + case sz_word: comprintf("\tsign_extend_16_rr(tmp,src);\n"); break; + case sz_long: comprintf("\ttmp=src;\n"); break; + default: assert(0); + } + comprintf("\tsub_l(dst,tmp);\n"); + genastore("dst", curi->dmode, "dstreg", sz_long, "dst"); + break; - case i_SUBX: + case i_SUBX: #ifdef DISABLE_I_SUBX - failure; + failure; #endif - isaddx; - genamode (curi->smode, "srcreg", curi->size, "src", 1, 0); - genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0); - genflags (flag_subx, curi->size, "", "src", "dst"); - genastore ("dst", curi->dmode, "dstreg", curi->size, "dst"); - break; + isaddx; + genamode(curi->smode, "srcreg", curi->size, "src", GENA_GETV_FETCH, GENA_MOVEM_DO_INC); + genamode(curi->dmode, "dstreg", curi->size, "dst", GENA_GETV_FETCH, GENA_MOVEM_DO_INC); + genflags(flag_subx, curi->size, "", "src", "dst"); + genastore("dst", curi->dmode, "dstreg", curi->size, "dst"); + break; - case i_SBCD: - failure; - /* I don't think so! */ - break; + case i_SBCD: + failure; + /* I don't think so! */ + break; - case i_ADD: + case i_ADD: #ifdef DISABLE_I_ADD - failure; + failure; #endif - genamode (curi->smode, "srcreg", curi->size, "src", 1, 0); - genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0); - genflags (flag_add, curi->size, "", "src", "dst"); - genastore ("dst", curi->dmode, "dstreg", curi->size, "dst"); - break; + genamode(curi->smode, "srcreg", curi->size, "src", GENA_GETV_FETCH, GENA_MOVEM_DO_INC); + genamode(curi->dmode, "dstreg", curi->size, "dst", GENA_GETV_FETCH, GENA_MOVEM_DO_INC); + genflags(flag_add, curi->size, "", "src", "dst"); + genastore("dst", curi->dmode, "dstreg", curi->size, "dst"); + break; - case i_ADDA: + case i_ADDA: #ifdef DISABLE_I_ADDA - failure; + failure; #endif - genamode (curi->smode, "srcreg", curi->size, "src", 1, 0); - genamode (curi->dmode, "dstreg", sz_long, "dst", 1, 0); - start_brace(); - comprintf("\tint tmp=scratchie++;\n"); - switch(curi->size) { - case sz_byte: comprintf("\tsign_extend_8_rr(tmp,src);\n"); break; - case sz_word: comprintf("\tsign_extend_16_rr(tmp,src);\n"); break; - case sz_long: comprintf("\ttmp=src;\n"); break; - default: assert(0); - } - comprintf("\tadd_l(dst,tmp);\n"); - genastore ("dst", curi->dmode, "dstreg", sz_long, "dst"); - break; + genamode(curi->smode, "srcreg", curi->size, "src", GENA_GETV_FETCH, GENA_MOVEM_DO_INC); + genamode(curi->dmode, "dstreg", sz_long, "dst", GENA_GETV_FETCH, GENA_MOVEM_DO_INC); + start_brace(); + comprintf("\tint tmp=scratchie++;\n"); + switch (curi->size) { + case sz_byte: comprintf("\tsign_extend_8_rr(tmp,src);\n"); break; + case sz_word: comprintf("\tsign_extend_16_rr(tmp,src);\n"); break; + case sz_long: comprintf("\ttmp=src;\n"); break; + default: assert(0); + } + comprintf("\tadd_l(dst,tmp);\n"); + genastore("dst", curi->dmode, "dstreg", sz_long, "dst"); + break; - case i_ADDX: + case i_ADDX: #ifdef DISABLE_I_ADDX - failure; + failure; #endif - isaddx; - genamode (curi->smode, "srcreg", curi->size, "src", 1, 0); - genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0); - start_brace(); - genflags (flag_addx, curi->size, "", "src", "dst"); - genastore ("dst", curi->dmode, "dstreg", curi->size, "dst"); - break; + isaddx; + genamode(curi->smode, "srcreg", curi->size, "src", GENA_GETV_FETCH, GENA_MOVEM_DO_INC); + genamode(curi->dmode, "dstreg", curi->size, "dst", GENA_GETV_FETCH, GENA_MOVEM_DO_INC); + start_brace(); + genflags(flag_addx, curi->size, "", "src", "dst"); + genastore("dst", curi->dmode, "dstreg", curi->size, "dst"); + break; - case i_ABCD: - failure; - /* No BCD maths for me.... */ - break; + case i_ABCD: + failure; + /* No BCD maths for me.... */ + break; - case i_NEG: + case i_NEG: #ifdef DISABLE_I_NEG - failure; + failure; #endif - genamode (curi->smode, "srcreg", curi->size, "src", 1, 0); - start_brace (); - comprintf("\tint dst=scratchie++;\n"); - comprintf("\tmov_l_ri(dst,0);\n"); - genflags (flag_sub, curi->size, "", "src", "dst"); - genastore ("dst", curi->smode, "srcreg", curi->size, "src"); - break; + genamode(curi->smode, "srcreg", curi->size, "src", GENA_GETV_FETCH, GENA_MOVEM_DO_INC); + start_brace(); + comprintf("\tint dst=scratchie++;\n"); + comprintf("\tmov_l_ri(dst,0);\n"); + genflags(flag_sub, curi->size, "", "src", "dst"); + genastore("dst", curi->smode, "srcreg", curi->size, "src"); + break; - case i_NEGX: + case i_NEGX: #ifdef DISABLE_I_NEGX - failure; + failure; #endif - isaddx; - genamode (curi->smode, "srcreg", curi->size, "src", 1, 0); - start_brace (); - comprintf("\tint dst=scratchie++;\n"); - comprintf("\tmov_l_ri(dst,0);\n"); - genflags (flag_subx, curi->size, "", "src", "dst"); - genastore ("dst", curi->smode, "srcreg", curi->size, "src"); - break; + isaddx; + genamode(curi->smode, "srcreg", curi->size, "src", GENA_GETV_FETCH, GENA_MOVEM_DO_INC); + start_brace(); + comprintf("\tint dst=scratchie++;\n"); + comprintf("\tmov_l_ri(dst,0);\n"); + genflags(flag_subx, curi->size, "", "src", "dst"); + genastore("dst", curi->smode, "srcreg", curi->size, "src"); + break; - case i_NBCD: - failure; - /* Nope! */ - break; + case i_NBCD: + failure; + /* Nope! */ + break; - case i_CLR: + case i_CLR: #ifdef DISABLE_I_CLR - failure; + failure; #endif - genamode (curi->smode, "srcreg", curi->size, "src", 2, 0); - start_brace(); - comprintf("\tint dst=scratchie++;\n"); - comprintf("\tmov_l_ri(dst,0);\n"); - genflags (flag_logical, curi->size, "dst", "", ""); - genastore ("dst", curi->smode, "srcreg", curi->size, "src"); - break; + genamode(curi->smode, "srcreg", curi->size, "src", GENA_GETV_FETCH_ALIGN, GENA_MOVEM_DO_INC); + start_brace(); + comprintf("\tint dst=scratchie++;\n"); + comprintf("\tmov_l_ri(dst,0);\n"); + genflags(flag_logical, curi->size, "dst", "", ""); + genastore("dst", curi->smode, "srcreg", curi->size, "src"); + break; - case i_NOT: + case i_NOT: #ifdef DISABLE_I_NOT - failure; + failure; #endif - genamode (curi->smode, "srcreg", curi->size, "src", 1, 0); - start_brace (); - comprintf("\tint dst=scratchie++;\n"); - comprintf("\tmov_l_ri(dst,0xffffffff);\n"); - genflags (flag_eor, curi->size, "", "src", "dst"); - genastore ("dst", curi->smode, "srcreg", curi->size, "src"); - break; + genamode(curi->smode, "srcreg", curi->size, "src", GENA_GETV_FETCH, GENA_MOVEM_DO_INC); + start_brace(); + comprintf("\tint dst=scratchie++;\n"); + comprintf("\tmov_l_ri(dst,0xffffffff);\n"); + genflags(flag_eor, curi->size, "", "src", "dst"); + genastore("dst", curi->smode, "srcreg", curi->size, "src"); + break; - case i_TST: + case i_TST: #ifdef DISABLE_I_TST - failure; + failure; #endif - genamode (curi->smode, "srcreg", curi->size, "src", 1, 0); - genflags (flag_logical, curi->size, "src", "", ""); - break; - case i_BCHG: - case i_BCLR: - case i_BSET: - case i_BTST: + genamode(curi->smode, "srcreg", curi->size, "src", GENA_GETV_FETCH, GENA_MOVEM_DO_INC); + genflags(flag_logical, curi->size, "src", "", ""); + break; + case i_BCHG: + case i_BCLR: + case i_BSET: + case i_BTST: #ifdef DISABLE_I_BCHG_BCLR_BSET_BTST - failure; + failure; #endif - genamode (curi->smode, "srcreg", curi->size, "src", 1, 0); - genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0); - start_brace(); - comprintf("\tint s=scratchie++;\n" - "\tint tmp=scratchie++;\n" - "\tmov_l_rr(s,src);\n"); - if (curi->size == sz_byte) - comprintf("\tand_l_ri(s,7);\n"); - else - comprintf("\tand_l_ri(s,31);\n"); + genamode(curi->smode, "srcreg", curi->size, "src", GENA_GETV_FETCH, GENA_MOVEM_DO_INC); + genamode(curi->dmode, "dstreg", curi->size, "dst", GENA_GETV_FETCH, GENA_MOVEM_DO_INC); + start_brace(); + comprintf("\tint s=scratchie++;\n" + "\tint tmp=scratchie++;\n" + "\tmov_l_rr(s,src);\n"); + if (curi->size == sz_byte) + comprintf("\tand_l_ri(s,7);\n"); + else + comprintf("\tand_l_ri(s,31);\n"); - { - const char* op; - int need_write=1; - - switch(curi->mnemo) { - case i_BCHG: op="btc"; break; - case i_BCLR: op="btr"; break; - case i_BSET: op="bts"; break; - case i_BTST: op="bt"; need_write=0; break; - default: assert(0); - } - comprintf("\t%s_l_rr(dst,s);\n" /* Answer now in C */ - "\tsbb_l(s,s);\n" /* s is 0 if bit was 0, -1 otherwise */ - "\tmake_flags_live();\n" /* Get the flags back */ - "\tdont_care_flags();\n",op); - if (!noflags) { - comprintf("\tstart_needflags();\n" + { + const char *op; + int need_write = 1; + + switch (curi->mnemo) { + case i_BCHG: op = "btc"; break; + case i_BCLR: op = "btr"; break; + case i_BSET: op = "bts"; break; + case i_BTST: op = "bt"; need_write = 0; break; + default: op = ""; assert(0); + } + comprintf("\t%s_l_rr(dst,s);\n" /* Answer now in C */ + "\tsbb_l(s,s);\n" /* s is 0 if bit was 0, -1 otherwise */ + "\tmake_flags_live();\n" /* Get the flags back */ + "\tdont_care_flags();\n", op); + if (!noflags) { + comprintf("\tstart_needflags();\n" "\tset_zero(s,tmp);\n" "\tlive_flags();\n" "\tend_needflags();\n"); + } + if (need_write) + genastore("dst", curi->dmode, "dstreg", curi->size, "dst"); } - if (need_write) - genastore ("dst", curi->dmode, "dstreg", curi->size, "dst"); - } - break; + break; - case i_CMPM: - case i_CMP: + case i_CMPM: + case i_CMP: #ifdef DISABLE_I_CMPM_CMP - failure; + failure; #endif - genamode (curi->smode, "srcreg", curi->size, "src", 1, 0); - genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0); - start_brace (); - genflags (flag_cmp, curi->size, "", "src", "dst"); - break; + genamode(curi->smode, "srcreg", curi->size, "src", GENA_GETV_FETCH, GENA_MOVEM_DO_INC); + genamode(curi->dmode, "dstreg", curi->size, "dst", GENA_GETV_FETCH, GENA_MOVEM_DO_INC); + start_brace(); + genflags(flag_cmp, curi->size, "", "src", "dst"); + break; - case i_CMPA: + case i_CMPA: #ifdef DISABLE_I_CMPA - failure; + failure; #endif - genamode (curi->smode, "srcreg", curi->size, "src", 1, 0); - genamode (curi->dmode, "dstreg", sz_long, "dst", 1, 0); - start_brace(); - comprintf("\tint tmps=scratchie++;\n"); - switch(curi->size) { - case sz_byte: comprintf("\tsign_extend_8_rr(tmps,src);\n"); break; - case sz_word: comprintf("\tsign_extend_16_rr(tmps,src);\n"); break; - case sz_long: comprintf("tmps=src;\n"); break; - default: assert(0); - } - genflags (flag_cmp, sz_long, "", "tmps", "dst"); - break; - /* The next two are coded a little unconventional, but they are doing - * weird things... */ + genamode(curi->smode, "srcreg", curi->size, "src", GENA_GETV_FETCH, GENA_MOVEM_DO_INC); + genamode(curi->dmode, "dstreg", sz_long, "dst", GENA_GETV_FETCH, GENA_MOVEM_DO_INC); + start_brace(); + comprintf("\tint tmps=scratchie++;\n"); + switch (curi->size) { + case sz_byte: comprintf("\tsign_extend_8_rr(tmps,src);\n"); break; + case sz_word: comprintf("\tsign_extend_16_rr(tmps,src);\n"); break; + case sz_long: comprintf("tmps=src;\n"); break; + default: assert(0); + } + genflags(flag_cmp, sz_long, "", "tmps", "dst"); + break; + /* The next two are coded a little unconventional, but they are doing + * weird things... */ - case i_MVPRM: - isjump; - failure; - break; + case i_MVPRM: + isjump; + failure; + break; - case i_MVPMR: - isjump; - failure; - break; + case i_MVPMR: + isjump; + failure; + break; - case i_MOVE: + case i_MOVE: #ifdef DISABLE_I_MOVE - failure; -#endif - switch(curi->dmode) { - case Dreg: - case Areg: - genamode (curi->smode, "srcreg", curi->size, "src", 1, 0); - genamode (curi->dmode, "dstreg", curi->size, "dst", 2, 0); - genflags (flag_mov, curi->size, "", "src", "dst"); - genastore ("dst", curi->dmode, "dstreg", curi->size, "dst"); - break; - default: /* It goes to memory, not a register */ - genamode (curi->smode, "srcreg", curi->size, "src", 1, 0); - genamode (curi->dmode, "dstreg", curi->size, "dst", 2, 0); - genflags (flag_logical, curi->size, "src", "", ""); - genastore ("src", curi->dmode, "dstreg", curi->size, "dst"); - break; - } - break; + failure; +#endif + switch (curi->dmode) { + case Dreg: + case Areg: + genamode(curi->smode, "srcreg", curi->size, "src", GENA_GETV_FETCH, GENA_MOVEM_DO_INC); + genamode(curi->dmode, "dstreg", curi->size, "dst", GENA_GETV_FETCH_ALIGN, GENA_MOVEM_DO_INC); + genflags(flag_mov, curi->size, "", "src", "dst"); + genastore("dst", curi->dmode, "dstreg", curi->size, "dst"); + break; + default: /* It goes to memory, not a register */ + genamode(curi->smode, "srcreg", curi->size, "src", GENA_GETV_FETCH, GENA_MOVEM_DO_INC); + genamode(curi->dmode, "dstreg", curi->size, "dst", GENA_GETV_FETCH_ALIGN, GENA_MOVEM_DO_INC); + genflags(flag_logical, curi->size, "src", "", ""); + genastore("src", curi->dmode, "dstreg", curi->size, "dst"); + break; + } + break; - case i_MOVEA: + case i_MOVEA: #ifdef DISABLE_I_MOVEA - failure; + failure; #endif - genamode (curi->smode, "srcreg", curi->size, "src", 1, 0); - genamode (curi->dmode, "dstreg", curi->size, "dst", 2, 0); + genamode(curi->smode, "srcreg", curi->size, "src", GENA_GETV_FETCH, GENA_MOVEM_DO_INC); + genamode(curi->dmode, "dstreg", curi->size, "dst", GENA_GETV_FETCH_ALIGN, GENA_MOVEM_DO_INC); - start_brace(); - comprintf("\tint tmps=scratchie++;\n"); - switch(curi->size) { - case sz_word: comprintf("\tsign_extend_16_rr(dst,src);\n"); break; - case sz_long: comprintf("\tmov_l_rr(dst,src);\n"); break; - default: assert(0); - } - genastore ("dst", curi->dmode, "dstreg", sz_long, "dst"); - break; + start_brace(); + comprintf("\tint tmps=scratchie++;\n"); + switch (curi->size) { + case sz_word: comprintf("\tsign_extend_16_rr(dst,src);\n"); break; + case sz_long: comprintf("\tmov_l_rr(dst,src);\n"); break; + default: assert(0); + } + genastore("dst", curi->dmode, "dstreg", sz_long, "dst"); + break; - case i_MVSR2: - isjump; - failure; - break; + case i_MVSR2: + isjump; + failure; + break; - case i_MV2SR: - isjump; - failure; - break; + case i_MV2SR: + isjump; + failure; + break; - case i_SWAP: + case i_SWAP: #ifdef DISABLE_I_SWAP - failure; + failure; #endif - genamode (curi->smode, "srcreg", sz_long, "src", 1, 0); - comprintf("\tdont_care_flags();\n"); - comprintf("\trol_l_ri(src,16);\n"); - genflags (flag_logical, sz_long, "src", "", ""); - genastore ("src", curi->smode, "srcreg", sz_long, "src"); - break; + genamode(curi->smode, "srcreg", sz_long, "src", GENA_GETV_FETCH, GENA_MOVEM_DO_INC); + comprintf("\tdont_care_flags();\n"); + comprintf("\trol_l_ri(src,16);\n"); + genflags(flag_logical, sz_long, "src", "", ""); + genastore("src", curi->smode, "srcreg", sz_long, "src"); + break; - case i_EXG: + case i_EXG: #ifdef DISABLE_I_EXG - failure; + failure; #endif - genamode (curi->smode, "srcreg", curi->size, "src", 1, 0); - genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0); - start_brace(); - comprintf("\tint tmp=scratchie++;\n" - "\tmov_l_rr(tmp,src);\n"); - genastore ("dst", curi->smode, "srcreg", curi->size, "src"); - genastore ("tmp", curi->dmode, "dstreg", curi->size, "dst"); - break; + genamode(curi->smode, "srcreg", curi->size, "src", GENA_GETV_FETCH, GENA_MOVEM_DO_INC); + genamode(curi->dmode, "dstreg", curi->size, "dst", GENA_GETV_FETCH, GENA_MOVEM_DO_INC); + start_brace(); + comprintf("\tint tmp=scratchie++;\n" + "\tmov_l_rr(tmp,src);\n"); + genastore("dst", curi->smode, "srcreg", curi->size, "src"); + genastore("tmp", curi->dmode, "dstreg", curi->size, "dst"); + break; - case i_EXT: + case i_EXT: #ifdef DISABLE_I_EXT - failure; + failure; #endif - genamode (curi->smode, "srcreg", sz_long, "src", 1, 0); - comprintf("\tdont_care_flags();\n"); - start_brace (); - switch (curi->size) - { - case sz_byte: - comprintf ("\tint dst = src;\n" - "\tsign_extend_8_rr(src,src);\n"); - break; - case sz_word: - comprintf ("\tint dst = scratchie++;\n" - "\tsign_extend_8_rr(dst,src);\n"); - break; - case sz_long: - comprintf ("\tint dst = src;\n" - "\tsign_extend_16_rr(src,src);\n"); - break; - default: - assert(0); - } - genflags (flag_logical, - curi->size == sz_word ? sz_word : sz_long, "dst", "", ""); - genastore ("dst", curi->smode, "srcreg", - curi->size == sz_word ? sz_word : sz_long, "src"); - break; + genamode(curi->smode, "srcreg", sz_long, "src", GENA_GETV_FETCH, GENA_MOVEM_DO_INC); + comprintf("\tdont_care_flags();\n"); + start_brace(); + switch (curi->size) + { + case sz_byte: + comprintf("\tint dst = src;\n" + "\tsign_extend_8_rr(src,src);\n"); + break; + case sz_word: + comprintf("\tint dst = scratchie++;\n" + "\tsign_extend_8_rr(dst,src);\n"); + break; + case sz_long: + comprintf("\tint dst = src;\n" + "\tsign_extend_16_rr(src,src);\n"); + break; + default: + assert(0); + } + genflags(flag_logical, + curi->size == sz_word ? sz_word : sz_long, "dst", "", ""); + genastore("dst", curi->smode, "srcreg", + curi->size == sz_word ? sz_word : sz_long, "src"); + break; - case i_MVMEL: + case i_MVMEL: #ifdef DISABLE_I_MVEL - failure; + failure; #endif - genmovemel (opcode); - break; + genmovemel(opcode); + break; - case i_MVMLE: + case i_MVMLE: #ifdef DISABLE_I_MVMLE - failure; + failure; #endif - genmovemle (opcode); - break; + genmovemle(opcode); + break; - case i_TRAP: - isjump; - failure; - break; + case i_TRAP: +#ifdef DISABLE_I_TRAP + failure; +#endif + isjump; + mayfail; + start_brace(); + comprintf(" int trapno = srcreg + 32;\n"); + gen_set_fault_pc(); + make_sr(); + comprintf(" compemu_enter_super(sr);\n"); + comprintf(" compemu_exc_make_frame(0, sr, ret, trapno, scratchie);\n"); + comprintf(" forget_about(ret);\n"); + /* m68k_setpc (get_long (regs.vbr + 4*nr)); */ + start_brace(); + comprintf(" int srca = scratchie++;\n"); + comprintf(" mov_l_rm(srca, (uintptr)®s.vbr);\n"); + comprintf(" mov_l_brR(srca, srca, MEMBaseDiff + trapno * 4); mid_bswap_32(srca);\n"); + comprintf(" mov_l_mr((uintptr)®s.pc, srca);\n"); + comprintf(" get_n_addr_jmp(srca, PC_P, scratchie);\n"); + comprintf(" mov_l_mr((uintptr)®s.pc_oldp, PC_P);\n"); + gen_update_next_handler(); + disasm_this_inst(); /* for debugging only */ + /* + * this currently deactivates this feature, since it does not work yet + */ + failure; + break; - case i_MVR2USP: - isjump; - failure; - break; + case i_MVR2USP: + isjump; + failure; + break; - case i_MVUSP2R: - isjump; - failure; - break; + case i_MVUSP2R: + isjump; + failure; + break; - case i_RESET: - isjump; - failure; - break; + case i_RESET: + isjump; + failure; + break; - case i_NOP: - break; + case i_NOP: + break; - case i_STOP: - isjump; - failure; - break; + case i_STOP: + isjump; + failure; + break; - case i_RTE: - isjump; - failure; - break; + case i_RTE: + isjump; + failure; + break; - case i_RTD: + case i_RTD: #ifdef DISABLE_I_RTD - failure; + failure; #endif - genamode (curi->smode, "srcreg", curi->size, "offs", 1, 0); - /* offs is constant */ - comprintf("\tadd_l_ri(offs,4);\n"); - start_brace(); - comprintf("\tint newad=scratchie++;\n" - "\treadlong(15,newad,scratchie);\n" - "\tmov_l_mr((uintptr)®s.pc,newad);\n" - "\tget_n_addr_jmp(newad,PC_P,scratchie);\n" - "\tmov_l_mr((uintptr)®s.pc_oldp,PC_P);\n" - "\tm68k_pc_offset=0;\n" - "\tadd_l(15,offs);\n"); - gen_update_next_handler(); - isjump; - break; + genamode(curi->smode, "srcreg", curi->size, "offs", GENA_GETV_FETCH, GENA_MOVEM_DO_INC); + /* offs is constant */ + comprintf("\tadd_l_ri(offs,4);\n"); + start_brace(); + comprintf("\tint newad=scratchie++;\n" + "\treadlong(SP_REG,newad,scratchie);\n" + "\tmov_l_mr((uintptr)®s.pc,newad);\n" + "\tget_n_addr_jmp(newad,PC_P,scratchie);\n" + "\tmov_l_mr((uintptr)®s.pc_oldp,PC_P);\n" + "\tm68k_pc_offset=0;\n" + "\tadd_l(SP_REG,offs);\n"); + gen_update_next_handler(); + isjump; + break; - case i_LINK: + case i_LINK: #ifdef DISABLE_I_LINK - failure; -#endif - genamode (curi->smode, "srcreg", sz_long, "src", 1, 0); - genamode (curi->dmode, "dstreg", curi->size, "offs", 1, 0); - comprintf("\tsub_l_ri(15,4);\n" - "\twritelong_clobber(15,src,scratchie);\n" - "\tmov_l_rr(src,15);\n"); - if (curi->size==sz_word) - comprintf("\tsign_extend_16_rr(offs,offs);\n"); - comprintf("\tadd_l(15,offs);\n"); - genastore ("src", curi->smode, "srcreg", sz_long, "src"); - break; + failure; +#endif + genamode(curi->smode, "srcreg", sz_long, "src", GENA_GETV_FETCH, GENA_MOVEM_DO_INC); + genamode(curi->dmode, "dstreg", curi->size, "offs", GENA_GETV_FETCH, GENA_MOVEM_DO_INC); + comprintf("\tsub_l_ri(SP_REG,4);\n" + "\twritelong_clobber(SP_REG,src,scratchie);\n" + "\tmov_l_rr(src,SP_REG);\n"); + if (curi->size == sz_word) + comprintf("\tsign_extend_16_rr(offs,offs);\n"); + comprintf("\tadd_l(SP_REG,offs);\n"); + genastore("src", curi->smode, "srcreg", sz_long, "src"); + break; - case i_UNLK: + case i_UNLK: #ifdef DISABLE_I_UNLK - failure; + failure; #endif - genamode (curi->smode, "srcreg", curi->size, "src", 1, 0); - comprintf("\tmov_l_rr(15,src);\n" - "\treadlong(15,src,scratchie);\n" - "\tadd_l_ri(15,4);\n"); - genastore ("src", curi->smode, "srcreg", curi->size, "src"); - break; + genamode(curi->smode, "srcreg", curi->size, "src", GENA_GETV_FETCH, GENA_MOVEM_DO_INC); + comprintf("\tmov_l_rr(SP_REG,src);\n" + "\treadlong(SP_REG,src,scratchie);\n" + "\tadd_l_ri(SP_REG,4);\n"); + genastore("src", curi->smode, "srcreg", curi->size, "src"); + break; - case i_RTS: + case i_RTS: #ifdef DISABLE_I_RTS - failure; -#endif - comprintf("\tint newad=scratchie++;\n" - "\treadlong(15,newad,scratchie);\n" - "\tmov_l_mr((uintptr)®s.pc,newad);\n" - "\tget_n_addr_jmp(newad,PC_P,scratchie);\n" - "\tmov_l_mr((uintptr)®s.pc_oldp,PC_P);\n" - "\tm68k_pc_offset=0;\n" - "\tlea_l_brr(15,15,4);\n"); - gen_update_next_handler(); - isjump; - break; + failure; +#endif + comprintf("\tint newad=scratchie++;\n" + "\treadlong(SP_REG,newad,scratchie);\n" + "\tmov_l_mr((uintptr)®s.pc,newad);\n" + "\tget_n_addr_jmp(newad,PC_P,scratchie);\n" + "\tmov_l_mr((uintptr)®s.pc_oldp,PC_P);\n" + "\tm68k_pc_offset=0;\n" + "\tlea_l_brr(SP_REG,SP_REG,4);\n"); + gen_update_next_handler(); + isjump; + break; - case i_TRAPV: - isjump; - failure; - break; + case i_TRAPV: + isjump; + failure; + break; - case i_RTR: - isjump; - failure; - break; + case i_RTR: + isjump; + failure; + break; - case i_JSR: + case i_JSR: #ifdef DISABLE_I_JSR - failure; + failure; #endif - isjump; - genamode (curi->smode, "srcreg", curi->size, "src", 0, 0); - start_brace(); - comprintf("\tuae_u32 retadd=start_pc+((char *)comp_pc_p-(char *)start_pc_p)+m68k_pc_offset;\n"); - comprintf("\tint ret=scratchie++;\n" - "\tmov_l_ri(ret,retadd);\n" - "\tsub_l_ri(15,4);\n" - "\twritelong_clobber(15,ret,scratchie);\n"); - comprintf("\tmov_l_mr((uintptr)®s.pc,srca);\n" - "\tget_n_addr_jmp(srca,PC_P,scratchie);\n" - "\tmov_l_mr((uintptr)®s.pc_oldp,PC_P);\n" - "\tm68k_pc_offset=0;\n"); - gen_update_next_handler(); - break; + isjump; + genamode(curi->smode, "srcreg", curi->size, "src", GENA_GETV_NO_FETCH, GENA_MOVEM_DO_INC); + start_brace(); + comprintf("\tuae_u32 retadd=start_pc+((char *)comp_pc_p-(char *)start_pc_p)+m68k_pc_offset;\n"); + comprintf("\tint ret=scratchie++;\n" + "\tmov_l_ri(ret,retadd);\n" + "\tsub_l_ri(SP_REG,4);\n" + "\twritelong_clobber(SP_REG,ret,scratchie);\n"); + comprintf("\tmov_l_mr((uintptr)®s.pc,srca);\n" + "\tget_n_addr_jmp(srca,PC_P,scratchie);\n" + "\tmov_l_mr((uintptr)®s.pc_oldp,PC_P);\n" + "\tm68k_pc_offset=0;\n"); + gen_update_next_handler(); + break; - case i_JMP: + case i_JMP: #ifdef DISABLE_I_JMP - failure; -#endif - isjump; - genamode (curi->smode, "srcreg", curi->size, "src", 0, 0); - comprintf("\tmov_l_mr((uintptr)®s.pc,srca);\n" - "\tget_n_addr_jmp(srca,PC_P,scratchie);\n" - "\tmov_l_mr((uintptr)®s.pc_oldp,PC_P);\n" - "\tm68k_pc_offset=0;\n"); - gen_update_next_handler(); - break; + failure; +#endif + isjump; + genamode(curi->smode, "srcreg", curi->size, "src", GENA_GETV_NO_FETCH, GENA_MOVEM_DO_INC); + comprintf("\tmov_l_mr((uintptr)®s.pc,srca);\n" + "\tget_n_addr_jmp(srca,PC_P,scratchie);\n" + "\tmov_l_mr((uintptr)®s.pc_oldp,PC_P);\n" + "\tm68k_pc_offset=0;\n"); + gen_update_next_handler(); + break; - case i_BSR: + case i_BSR: #ifdef DISABLE_I_BSR - failure; + failure; #endif - is_const_jump; - genamode (curi->smode, "srcreg", curi->size, "src", 1, 0); - start_brace(); - comprintf("\tuae_u32 retadd=start_pc+((char *)comp_pc_p-(char *)start_pc_p)+m68k_pc_offset;\n"); - comprintf("\tint ret=scratchie++;\n" - "\tmov_l_ri(ret,retadd);\n" - "\tsub_l_ri(15,4);\n" - "\twritelong_clobber(15,ret,scratchie);\n"); - comprintf("\tadd_l_ri(src,m68k_pc_offset_thisinst+2);\n"); - comprintf("\tm68k_pc_offset=0;\n"); - comprintf("\tadd_l(PC_P,src);\n"); - - comprintf("\tcomp_pc_p=(uae_u8*)(uintptr)get_const(PC_P);\n"); - break; + is_const_jump; + genamode(curi->smode, "srcreg", curi->size, "src", GENA_GETV_FETCH, GENA_MOVEM_DO_INC); + start_brace(); + comprintf("\tuae_u32 retadd=start_pc+((char *)comp_pc_p-(char *)start_pc_p)+m68k_pc_offset;\n"); + comprintf("\tint ret=scratchie++;\n" + "\tmov_l_ri(ret,retadd);\n" + "\tsub_l_ri(SP_REG,4);\n" + "\twritelong_clobber(SP_REG,ret,scratchie);\n"); + comprintf("\tadd_l_ri(src,m68k_pc_offset_thisinst+2);\n"); + comprintf("\tm68k_pc_offset=0;\n"); + comprintf("\tadd_l(PC_P,src);\n"); + + comprintf("\tcomp_pc_p=(uae_u8*)(uintptr)get_const(PC_P);\n"); + gen_update_next_handler(); + break; - case i_Bcc: + case i_Bcc: #ifdef DISABLE_I_BCC - failure; -#endif - comprintf("\tuae_u32 v,v1,v2;\n"); - genamode (curi->smode, "srcreg", curi->size, "src", 1, 0); - /* That source is an immediate, so we can clobber it with abandon */ - switch(curi->size) { - case sz_byte: comprintf("\tsign_extend_8_rr(src,src);\n"); break; - case sz_word: comprintf("\tsign_extend_16_rr(src,src);\n"); break; - case sz_long: break; - } - comprintf("\tsub_l_ri(src,m68k_pc_offset-m68k_pc_offset_thisinst-2);\n"); - /* Leave the following as "add" --- it will allow it to be optimized - away due to src being a constant ;-) */ - comprintf("\tadd_l_ri(src,(uintptr)comp_pc_p);\n"); - comprintf("\tmov_l_ri(PC_P,(uintptr)comp_pc_p);\n"); - /* Now they are both constant. Might as well fold in m68k_pc_offset */ - comprintf("\tadd_l_ri(src,m68k_pc_offset);\n"); - comprintf("\tadd_l_ri(PC_P,m68k_pc_offset);\n"); - comprintf("\tm68k_pc_offset=0;\n"); - - if (curi->cc>=2) { - comprintf("\tv1=get_const(PC_P);\n" - "\tv2=get_const(src);\n" - "\tregister_branch(v1,v2,%d);\n", - cond_codes[curi->cc]); - comprintf("\tmake_flags_live();\n"); /* Load the flags */ - isjump; - } - else { - is_const_jump; - } + failure; +#endif + comprintf("\tuae_u32 v,v1,v2;\n"); + genamode(curi->smode, "srcreg", curi->size, "src", GENA_GETV_FETCH, GENA_MOVEM_DO_INC); + /* That source is an immediate, so we can clobber it with abandon */ + switch (curi->size) { + case sz_byte: comprintf("\tsign_extend_8_rr(src,src);\n"); break; + case sz_word: comprintf("\tsign_extend_16_rr(src,src);\n"); break; + case sz_long: break; + } + comprintf("\tsub_l_ri(src,m68k_pc_offset-m68k_pc_offset_thisinst-2);\n"); + /* Leave the following as "add" --- it will allow it to be optimized + away due to src being a constant ;-) */ + comprintf("\tadd_l_ri(src,(uintptr)comp_pc_p);\n"); + comprintf("\tmov_l_ri(PC_P,(uintptr)comp_pc_p);\n"); + /* Now they are both constant. Might as well fold in m68k_pc_offset */ + comprintf("\tadd_l_ri(src,m68k_pc_offset);\n"); + comprintf("\tadd_l_ri(PC_P,m68k_pc_offset);\n"); + comprintf("\tm68k_pc_offset=0;\n"); + + if (curi->cc >= 2) { + comprintf("\tv1=get_const(PC_P);\n" + "\tv2=get_const(src);\n" + "\tregister_branch(v1,v2,%d);\n", + cond_codes[curi->cc]); + comprintf("\tmake_flags_live();\n"); /* Load the flags */ + isjump; + } else { + is_const_jump; + } - switch(curi->cc) { - case 0: /* Unconditional jump */ - comprintf("\tmov_l_rr(PC_P,src);\n"); - comprintf("\tcomp_pc_p=(uae_u8*)(uintptr)get_const(PC_P);\n"); - break; - case 1: break; /* This is silly! */ - case 8: failure; break; /* Work out details! FIXME */ - case 9: failure; break; /* Not critical, though! */ - - case 2: - case 3: - case 4: - case 5: - case 6: - case 7: - case 10: - case 11: - case 12: - case 13: - case 14: - case 15: - break; - default: assert(0); - } - break; + switch (curi->cc) { + case 0: /* Unconditional jump */ + comprintf("\tmov_l_rr(PC_P,src);\n"); + comprintf("\tcomp_pc_p=(uae_u8*)(uintptr)get_const(PC_P);\n"); + break; + case 1: break; /* This is silly! */ + case 8: failure; break; /* Work out details! FIXME */ + case 9: failure; break; /* Not critical, though! */ + + case 2: + case 3: + case 4: + case 5: + case 6: + case 7: + case 10: + case 11: + case 12: + case 13: + case 14: + case 15: + break; + default: assert(0); + } + break; - case i_LEA: + case i_LEA: #ifdef DISABLE_I_LEA - failure; + failure; #endif - genamode (curi->smode, "srcreg", curi->size, "src", 0, 0); - genamode (curi->dmode, "dstreg", curi->size, "dst", 2, 0); - genastore ("srca", curi->dmode, "dstreg", curi->size, "dst"); - break; + genamode(curi->smode, "srcreg", curi->size, "src", GENA_GETV_NO_FETCH, GENA_MOVEM_DO_INC); + genamode(curi->dmode, "dstreg", curi->size, "dst", GENA_GETV_FETCH_ALIGN, GENA_MOVEM_DO_INC); + genastore("srca", curi->dmode, "dstreg", curi->size, "dst"); + break; - case i_PEA: + case i_PEA: #ifdef DISABLE_I_PEA - failure; -#endif - if (table68k[opcode].smode==Areg || - table68k[opcode].smode==Aind || - table68k[opcode].smode==Aipi || - table68k[opcode].smode==Apdi || - table68k[opcode].smode==Ad16 || - table68k[opcode].smode==Ad8r) - comprintf("if (srcreg==7) dodgy=1;\n"); - - genamode (curi->smode, "srcreg", curi->size, "src", 0, 0); - genamode (Apdi, "7", sz_long, "dst", 2, 0); - genastore ("srca", Apdi, "7", sz_long, "dst"); - break; + failure; +#endif + if (table68k[opcode].smode == Areg || + table68k[opcode].smode == Aind || + table68k[opcode].smode == Aipi || + table68k[opcode].smode == Apdi || + table68k[opcode].smode == Ad16 || + table68k[opcode].smode == Ad8r) + comprintf("if (srcreg==7) dodgy=1;\n"); + + genamode(curi->smode, "srcreg", curi->size, "src", GENA_GETV_NO_FETCH, GENA_MOVEM_DO_INC); + genamode(Apdi, "7", sz_long, "dst", GENA_GETV_FETCH_ALIGN, GENA_MOVEM_DO_INC); + genastore("srca", Apdi, "7", sz_long, "dst"); + break; - case i_DBcc: + case i_DBcc: #ifdef DISABLE_I_DBCC - failure; + failure; #endif - isjump; - uses_cmov; - genamode (curi->smode, "srcreg", curi->size, "src", 1, 0); - genamode (curi->dmode, "dstreg", curi->size, "offs", 1, 0); + isjump; + uses_cmov; + genamode(curi->smode, "srcreg", curi->size, "src", GENA_GETV_FETCH, GENA_MOVEM_DO_INC); + genamode(curi->dmode, "dstreg", curi->size, "offs", GENA_GETV_FETCH, GENA_MOVEM_DO_INC); - /* That offs is an immediate, so we can clobber it with abandon */ - switch(curi->size) { - case sz_word: comprintf("\tsign_extend_16_rr(offs,offs);\n"); break; - default: assert(0); /* Seems this only comes in word flavour */ - } - comprintf("\tsub_l_ri(offs,m68k_pc_offset-m68k_pc_offset_thisinst-2);\n"); - comprintf("\tadd_l_ri(offs,(uintptr)comp_pc_p);\n"); /* New PC, - once the - offset_68k is - * also added */ - /* Let's fold in the m68k_pc_offset at this point */ - comprintf("\tadd_l_ri(offs,m68k_pc_offset);\n"); - comprintf("\tadd_l_ri(PC_P,m68k_pc_offset);\n"); - comprintf("\tm68k_pc_offset=0;\n"); + /* That offs is an immediate, so we can clobber it with abandon */ + switch (curi->size) { + case sz_word: comprintf("\tsign_extend_16_rr(offs,offs);\n"); break; + default: assert(0); /* Seems this only comes in word flavour */ + } + comprintf("\tsub_l_ri(offs,m68k_pc_offset-m68k_pc_offset_thisinst-2);\n"); + comprintf("\tadd_l_ri(offs,(uintptr)comp_pc_p);\n"); /* New PC, + once the + offset_68k is + * also added */ + /* Let's fold in the m68k_pc_offset at this point */ + comprintf("\tadd_l_ri(offs,m68k_pc_offset);\n"); + comprintf("\tadd_l_ri(PC_P,m68k_pc_offset);\n"); + comprintf("\tm68k_pc_offset=0;\n"); - start_brace(); - comprintf("\tint nsrc=scratchie++;\n"); + start_brace(); + comprintf("\tint nsrc=scratchie++;\n"); - if (curi->cc>=2) { - comprintf("\tmake_flags_live();\n"); /* Load the flags */ - } + if (curi->cc >= 2) { + comprintf("\tmake_flags_live();\n"); /* Load the flags */ + } - assert (curi->size==sz_word); - - switch(curi->cc) { - case 0: /* This is an elaborate nop? */ - break; - case 1: - comprintf("\tstart_needflags();\n"); - comprintf("\tsub_w_ri(src,1);\n"); - comprintf("\t end_needflags();\n"); - start_brace(); - comprintf("\tuae_u32 v2,v;\n" - "\tuae_u32 v1=get_const(PC_P);\n"); - comprintf("\tv2=get_const(offs);\n" - "\tregister_branch(v1,v2,%d);\n", NATIVE_CC_CC); - break; - - case 8: failure; break; /* Work out details! FIXME */ - case 9: failure; break; /* Not critical, though! */ - - case 2: - case 3: - case 4: - case 5: - case 6: - case 7: - case 10: - case 11: - case 12: - case 13: - case 14: - case 15: - comprintf("\tmov_l_rr(nsrc,src);\n"); - comprintf("\tlea_l_brr(scratchie,src,(uae_s32)-1);\n" - "\tmov_w_rr(src,scratchie);\n"); - comprintf("\tcmov_l_rr(offs,PC_P,%d);\n", - cond_codes[curi->cc]); - comprintf("\tcmov_l_rr(src,nsrc,%d);\n", - cond_codes[curi->cc]); - /* OK, now for cc=true, we have src==nsrc and offs==PC_P, - so whether we move them around doesn't matter. However, - if cc=false, we have offs==jump_pc, and src==nsrc-1 */ - - comprintf("\t start_needflags();\n"); - comprintf("\ttest_w_rr(nsrc,nsrc);\n"); - comprintf("\t end_needflags();\n"); - comprintf("\tcmov_l_rr(PC_P,offs,%d);\n", NATIVE_CC_NE); - break; - default: assert(0); - } - genastore ("src", curi->smode, "srcreg", curi->size, "src"); - gen_update_next_handler(); - break; + assert(curi->size == sz_word); + + switch (curi->cc) { + case 0: /* This is an elaborate nop? */ + break; + case 1: + comprintf("\tstart_needflags();\n"); + comprintf("\tsub_w_ri(src,1);\n"); + comprintf("\tend_needflags();\n"); + start_brace(); + comprintf("\tuae_u32 v2,v;\n" + "\tuae_u32 v1=get_const(PC_P);\n"); + comprintf("\tv2=get_const(offs);\n" + "\tregister_branch(v1,v2,%d);\n", NATIVE_CC_CC); + break; + + case 8: failure; break; /* Work out details! FIXME */ + case 9: failure; break; /* Not critical, though! */ + + case 2: + case 3: + case 4: + case 5: + case 6: + case 7: + case 10: + case 11: + case 12: + case 13: + case 14: + case 15: + comprintf("\tmov_l_rr(nsrc,src);\n"); + comprintf("\tlea_l_brr(scratchie,src,(uae_s32)-1);\n" + "\tmov_w_rr(src,scratchie);\n"); + comprintf("\tcmov_l_rr(offs,PC_P,%d);\n", + cond_codes[curi->cc]); + comprintf("\tcmov_l_rr(src,nsrc,%d);\n", + cond_codes[curi->cc]); + /* OK, now for cc=true, we have src==nsrc and offs==PC_P, + so whether we move them around doesn't matter. However, + if cc=false, we have offs==jump_pc, and src==nsrc-1 */ + + comprintf("\tstart_needflags();\n"); + comprintf("\ttest_w_rr(nsrc,nsrc);\n"); + comprintf("\tend_needflags();\n"); + comprintf("\tcmov_l_rr(PC_P,offs,%d);\n", NATIVE_CC_NE); + break; + default: assert(0); + } + genastore("src", curi->smode, "srcreg", curi->size, "src"); + gen_update_next_handler(); + break; - case i_Scc: + case i_Scc: #ifdef DISABLE_I_SCC - failure; -#endif - genamode (curi->smode, "srcreg", curi->size, "src", 2, 0); - start_brace (); - comprintf ("\tint val = scratchie++;\n"); - - /* We set val to 0 if we really should use 255, and to 1 for real 0 */ - switch(curi->cc) { - case 0: /* Unconditional set */ - comprintf("\tmov_l_ri(val,0);\n"); - break; - case 1: - /* Unconditional not-set */ - comprintf("\tmov_l_ri(val,1);\n"); - break; - case 8: failure; break; /* Work out details! FIXME */ - case 9: failure; break; /* Not critical, though! */ - - case 2: - case 3: - case 4: - case 5: - case 6: - case 7: - case 10: - case 11: - case 12: - case 13: - case 14: - case 15: - comprintf("\tmake_flags_live();\n"); /* Load the flags */ - /* All condition codes can be inverted by changing the LSB */ - comprintf("\tsetcc(val,%d);\n", - cond_codes[curi->cc]^1); break; - default: assert(0); - } - comprintf("\tsub_b_ri(val,1);\n"); - genastore ("val", curi->smode, "srcreg", curi->size, "src"); - break; + failure; +#endif + genamode(curi->smode, "srcreg", curi->size, "src", GENA_GETV_FETCH_ALIGN, GENA_MOVEM_DO_INC); + start_brace(); + comprintf("\tint val = scratchie++;\n"); - case i_DIVU: - isjump; - failure; - break; + /* We set val to 0 if we really should use 255, and to 1 for real 0 */ + switch (curi->cc) { + case 0: /* Unconditional set */ + comprintf("\tmov_l_ri(val,0);\n"); + break; + case 1: + /* Unconditional not-set */ + comprintf("\tmov_l_ri(val,1);\n"); + break; + case 8: failure; break; /* Work out details! FIXME */ + case 9: failure; break; /* Not critical, though! */ + + case 2: + case 3: + case 4: + case 5: + case 6: + case 7: + case 10: + case 11: + case 12: + case 13: + case 14: + case 15: + comprintf("\tmake_flags_live();\n"); /* Load the flags */ + /* All condition codes can be inverted by changing the LSB */ + comprintf("\tsetcc(val,%d);\n", + cond_codes[curi->cc] ^ 1); break; + default: assert(0); + } + comprintf("\tsub_b_ri(val,1);\n"); + genastore("val", curi->smode, "srcreg", curi->size, "src"); + break; - case i_DIVS: - isjump; - failure; - break; + case i_DIVU: + isjump; + failure; + break; + + case i_DIVS: + isjump; + failure; + break; - case i_MULU: + case i_MULU: #ifdef DISABLE_I_MULU - failure; -#endif - comprintf("\tdont_care_flags();\n"); - genamode (curi->smode, "srcreg", sz_word, "src", 1, 0); - genamode (curi->dmode, "dstreg", sz_word, "dst", 1, 0); - /* To do 16x16 unsigned multiplication, we actually use - 32x32 signed, and zero-extend the registers first. - That solves the problem of MUL needing dedicated registers - on the x86 */ - comprintf("\tzero_extend_16_rr(scratchie,src);\n" - "\tzero_extend_16_rr(dst,dst);\n" - "\timul_32_32(dst,scratchie);\n"); - genflags (flag_logical, sz_long, "dst", "", ""); - genastore ("dst", curi->dmode, "dstreg", sz_long, "dst"); - break; + failure; +#endif + comprintf("\tdont_care_flags();\n"); + genamode(curi->smode, "srcreg", sz_word, "src", GENA_GETV_FETCH, GENA_MOVEM_DO_INC); + genamode(curi->dmode, "dstreg", sz_word, "dst", GENA_GETV_FETCH, GENA_MOVEM_DO_INC); + /* To do 16x16 unsigned multiplication, we actually use + 32x32 signed, and zero-extend the registers first. + That solves the problem of MUL needing dedicated registers + on the x86 */ + comprintf("\tzero_extend_16_rr(scratchie,src);\n" + "\tzero_extend_16_rr(dst,dst);\n" + "\timul_32_32(dst,scratchie);\n"); + genflags(flag_logical, sz_long, "dst", "", ""); + genastore("dst", curi->dmode, "dstreg", sz_long, "dst"); + break; - case i_MULS: + case i_MULS: #ifdef DISABLE_I_MULS - failure; -#endif - comprintf("\tdont_care_flags();\n"); - genamode (curi->smode, "srcreg", sz_word, "src", 1, 0); - genamode (curi->dmode, "dstreg", sz_word, "dst", 1, 0); - comprintf("\tsign_extend_16_rr(scratchie,src);\n" - "\tsign_extend_16_rr(dst,dst);\n" - "\timul_32_32(dst,scratchie);\n"); - genflags (flag_logical, sz_long, "dst", "", ""); - genastore ("dst", curi->dmode, "dstreg", sz_long, "dst"); - break; + failure; +#endif + comprintf("\tdont_care_flags();\n"); + genamode(curi->smode, "srcreg", sz_word, "src", GENA_GETV_FETCH, GENA_MOVEM_DO_INC); + genamode(curi->dmode, "dstreg", sz_word, "dst", GENA_GETV_FETCH, GENA_MOVEM_DO_INC); + comprintf("\tsign_extend_16_rr(scratchie,src);\n" + "\tsign_extend_16_rr(dst,dst);\n" + "\timul_32_32(dst,scratchie);\n"); + genflags(flag_logical, sz_long, "dst", "", ""); + genastore("dst", curi->dmode, "dstreg", sz_long, "dst"); + break; - case i_CHK: - isjump; - failure; - break; + case i_CHK: + isjump; + failure; + break; - case i_CHK2: - isjump; - failure; - break; + case i_CHK2: + isjump; + failure; + break; + + case i_ASR: +#ifdef DISABLE_I_ASR + failure; +#endif + mayfail; + if (curi->smode == Dreg) { + comprintf( + " if ((uae_u32)srcreg==(uae_u32)dstreg) {\n" + " FAIL(1);\n" + " " RETURN "\n" + " }\n"); + start_brace(); + } + comprintf("\tdont_care_flags();\n"); - case i_ASR: -#ifdef DISABLE_I_ASR - failure; -#endif - mayfail; - if (curi->smode==Dreg) { - comprintf("if ((uae_u32)srcreg==(uae_u32)dstreg) {\n" - " FAIL(1);\n" - " " RETURN "\n" - "} \n"); - start_brace(); - } - comprintf("\tdont_care_flags();\n"); + genamode(curi->smode, "srcreg", curi->size, "cnt", GENA_GETV_FETCH, GENA_MOVEM_DO_INC); + genamode(curi->dmode, "dstreg", curi->size, "data", GENA_GETV_FETCH, GENA_MOVEM_DO_INC); - genamode (curi->smode, "srcreg", curi->size, "cnt", 1, 0); - genamode (curi->dmode, "dstreg", curi->size, "data", 1, 0); - if (curi->smode!=immi) { - if (!noflags) { - uses_cmov; start_brace(); - comprintf("\tint highmask;\n" - "\tint width;\n" - "\tint cdata=scratchie++;\n" - "\tint tmpcnt=scratchie++;\n" - "\tint highshift=scratchie++;\n"); - comprintf("\tmov_l_rr(tmpcnt,cnt);\n" - "\tand_l_ri(tmpcnt,63);\n" - "\tmov_l_ri(cdata,0);\n" - "\tcmov_l_rr(cdata,data,%d);\n", NATIVE_CC_NE); - /* cdata is now either data (for shift count!=0) or - 0 (for shift count==0) */ - switch(curi->size) { - case sz_byte: comprintf("\tshra_b_rr(data,cnt);\n" - "\thighmask=0x38;\n" - "\twidth=8;\n"); - break; - case sz_word: comprintf("\tshra_w_rr(data,cnt);\n" - "\thighmask=0x30;\n" - "\twidth=16;\n"); - break; - case sz_long: comprintf("\tshra_l_rr(data,cnt);\n" - "\thighmask=0x20;\n" - "\twidth=32;\n"); - break; - default: assert(0); - } - comprintf("test_l_ri(cnt,highmask);\n" - "mov_l_ri(highshift,0);\n" - "mov_l_ri(scratchie,width/2);\n" - "cmov_l_rr(highshift,scratchie,%d);\n", NATIVE_CC_NE); - /* The x86 masks out bits, so we now make sure that things - really get shifted as much as planned */ - switch(curi->size) { - case sz_byte: comprintf("\tshra_b_rr(data,highshift);\n");break; - case sz_word: comprintf("\tshra_w_rr(data,highshift);\n");break; - case sz_long: comprintf("\tshra_l_rr(data,highshift);\n");break; - default: assert(0); - } - /* And again */ - switch(curi->size) { - case sz_byte: comprintf("\tshra_b_rr(data,highshift);\n");break; - case sz_word: comprintf("\tshra_w_rr(data,highshift);\n");break; - case sz_long: comprintf("\tshra_l_rr(data,highshift);\n");break; - default: assert(0); - } - - /* Result of shift is now in data. Now we need to determine - the carry by shifting cdata one less */ - comprintf("\tsub_l_ri(tmpcnt,1);\n"); - switch(curi->size) { - case sz_byte: comprintf("\tshra_b_rr(cdata,tmpcnt);\n");break; - case sz_word: comprintf("\tshra_w_rr(cdata,tmpcnt);\n");break; - case sz_long: comprintf("\tshra_l_rr(cdata,tmpcnt);\n");break; - default: assert(0); - } - /* If the shift count was higher than the width, we need - to pick up the sign from data */ - comprintf("test_l_ri(tmpcnt,highmask);\n" - "cmov_l_rr(cdata,data,%d);\n", NATIVE_CC_NE); + if (!noflags) + comprintf("\tstart_needflags();\n"); + if (curi->smode != immi) { + uses_cmov; + start_brace(); + comprintf("\tint zero = scratchie++;\n"); + comprintf("\tint tmpcnt = scratchie++;\n"); + comprintf("\tint minus1 = scratchie++;\n"); + comprintf("\tint cdata = minus1;\n"); + comprintf("\tmov_l_rr(tmpcnt,cnt);\n"); + comprintf("\tand_l_ri(tmpcnt,63);\n"); + comprintf("\tmov_l_ri(zero, 0);\n"); + comprintf("\tmov_l_ri(minus1, -1);\n"); + switch (curi->size) { + case sz_byte: + comprintf("\ttest_b_rr(data,data);\n"); + comprintf("\tcmov_l_rr(zero, minus1, NATIVE_CC_MI);\n"); + comprintf("\ttest_l_ri(tmpcnt, 0x38);\n"); + comprintf("\tmov_l_rr(cdata,data);\n"); + comprintf("\tcmov_l_rr(cdata, zero, NATIVE_CC_NE);\n"); + comprintf("\tshra_b_rr(cdata,tmpcnt);\n"); + comprintf("\tmov_b_rr(data,cdata);\n"); + break; + case sz_word: + comprintf("\ttest_w_rr(data,data);\n"); + comprintf("\tcmov_l_rr(zero, minus1, NATIVE_CC_MI);\n"); + comprintf("\ttest_l_ri(tmpcnt, 0x30);\n"); + comprintf("\tmov_l_rr(cdata,data);\n"); + comprintf("\tcmov_l_rr(cdata, zero, NATIVE_CC_NE);\n"); + comprintf("\tshra_w_rr(cdata,tmpcnt);\n"); + comprintf("\tmov_w_rr(data,cdata);\n"); + break; + case sz_long: + comprintf("\ttest_l_rr(data,data);\n"); + comprintf("\tcmov_l_rr(zero, minus1, NATIVE_CC_MI);\n"); + comprintf("\ttest_l_ri(tmpcnt, 0x20);\n"); + comprintf("\tmov_l_rr(cdata,data);\n"); + comprintf("\tcmov_l_rr(cdata, zero, NATIVE_CC_NE);\n"); + comprintf("\tshra_l_rr(cdata,tmpcnt);\n"); + comprintf("\tmov_l_rr(data,cdata);\n"); + break; + default: assert(0); + } + /* Result of shift is now in data. */ + } else { + switch (curi->size) { + case sz_byte: comprintf("\tshra_b_ri(data,srcreg);\n"); break; + case sz_word: comprintf("\tshra_w_ri(data,srcreg);\n"); break; + case sz_long: comprintf("\tshra_l_ri(data,srcreg);\n"); break; + default: assert(0); + } + } /* And create the flags */ - comprintf("\tstart_needflags();\n"); - comprintf("\tif (needed_flags & FLAG_ZNV)\n"); - switch(curi->size) { - case sz_byte: comprintf("\t test_b_rr(data,data);\n"); break; - case sz_word: comprintf("\t test_w_rr(data,data);\n"); break; - case sz_long: comprintf("\t test_l_rr(data,data);\n"); break; - } - comprintf("\t bt_l_ri(cdata,0);\n"); /* Set C */ - comprintf("\t live_flags();\n"); - comprintf("\t end_needflags();\n"); - comprintf("\t duplicate_carry();\n"); - comprintf("if (!(needed_flags & FLAG_CZNV)) dont_care_flags();\n"); - genastore ("data", curi->dmode, "dstreg", curi->size, "data"); - } - else { - uses_cmov; - start_brace(); - comprintf("\tint highmask;\n" - "\tint width;\n" - "\tint highshift=scratchie++;\n"); - switch(curi->size) { - case sz_byte: comprintf("\tshra_b_rr(data,cnt);\n" - "\thighmask=0x38;\n" - "\twidth=8;\n"); - break; - case sz_word: comprintf("\tshra_w_rr(data,cnt);\n" - "\thighmask=0x30;\n" - "\twidth=16;\n"); - break; - case sz_long: comprintf("\tshra_l_rr(data,cnt);\n" - "\thighmask=0x20;\n" - "\twidth=32;\n"); - break; - default: assert(0); - } - comprintf("test_l_ri(cnt,highmask);\n" - "mov_l_ri(highshift,0);\n" - "mov_l_ri(scratchie,width/2);\n" - "cmov_l_rr(highshift,scratchie,%d);\n",NATIVE_CC_NE); - /* The x86 masks out bits, so we now make sure that things - really get shifted as much as planned */ - switch(curi->size) { - case sz_byte: comprintf("\tshra_b_rr(data,highshift);\n");break; - case sz_word: comprintf("\tshra_w_rr(data,highshift);\n");break; - case sz_long: comprintf("\tshra_l_rr(data,highshift);\n");break; - default: assert(0); - } - /* And again */ - switch(curi->size) { - case sz_byte: comprintf("\tshra_b_rr(data,highshift);\n");break; - case sz_word: comprintf("\tshra_w_rr(data,highshift);\n");break; - case sz_long: comprintf("\tshra_l_rr(data,highshift);\n");break; - default: assert(0); - } - genastore ("data", curi->dmode, "dstreg", curi->size, "data"); - } - } - else { - start_brace(); - comprintf("\tint tmp=scratchie++;\n" - "\tint bp;\n" - "\tmov_l_rr(tmp,data);\n"); - switch(curi->size) { - case sz_byte: comprintf("\tshra_b_ri(data,srcreg);\n" - "\tbp=srcreg-1;\n"); break; - case sz_word: comprintf("\tshra_w_ri(data,srcreg);\n" - "\tbp=srcreg-1;\n"); break; - case sz_long: comprintf("\tshra_l_ri(data,srcreg);\n" - "\tbp=srcreg-1;\n"); break; - default: assert(0); - } - - if (!noflags) { - comprintf("\tstart_needflags();\n"); - comprintf("\tif (needed_flags & FLAG_ZNV)\n"); - switch(curi->size) { - case sz_byte: comprintf("\t test_b_rr(data,data);\n"); break; - case sz_word: comprintf("\t test_w_rr(data,data);\n"); break; - case sz_long: comprintf("\t test_l_rr(data,data);\n"); break; - } - comprintf("\t bt_l_ri(tmp,bp);\n"); /* Set C */ - comprintf("\t live_flags();\n"); - comprintf("\t end_needflags();\n"); - comprintf("\t duplicate_carry();\n"); - comprintf("if (!(needed_flags & FLAG_CZNV)) dont_care_flags();\n"); - } - genastore ("data", curi->dmode, "dstreg", curi->size, "data"); - } - break; + if (!noflags) { + comprintf("\tlive_flags();\n"); + comprintf("\tend_needflags();\n"); + if (curi->smode != immi) + comprintf("\tsetcc_for_cntzero(tmpcnt, data, %d);\n", curi->size == sz_byte ? 1 : curi->size == sz_word ? 2 : 4); + else + comprintf("\tduplicate_carry();\n"); + comprintf("if (!(needed_flags & FLAG_CZNV)) dont_care_flags();\n"); + } + genastore("data", curi->dmode, "dstreg", curi->size, "data"); + break; - case i_ASL: + case i_ASL: #ifdef DISABLE_I_ASL - failure; -#endif - mayfail; - if (curi->smode==Dreg) { - comprintf("if ((uae_u32)srcreg==(uae_u32)dstreg) {\n" - " FAIL(1);\n" - " " RETURN "\n" - "} \n"); - start_brace(); - } - comprintf("\tdont_care_flags();\n"); - /* Except for the handling of the V flag, this is identical to - LSL. The handling of V is, uhm, unpleasant, so if it's needed, - let the normal emulation handle it. Shoulders of giants kinda - thing ;-) */ - comprintf("if (needed_flags & FLAG_V) {\n" - " FAIL(1);\n" - " " RETURN "\n" - "} \n"); - - genamode (curi->smode, "srcreg", curi->size, "cnt", 1, 0); - genamode (curi->dmode, "dstreg", curi->size, "data", 1, 0); - if (curi->smode!=immi) { - if (!noflags) { - uses_cmov; + failure; +#endif + mayfail; + if (curi->smode == Dreg) { + comprintf( + " if ((uae_u32)srcreg==(uae_u32)dstreg) {\n" + " FAIL(1);\n" + " " RETURN "\n" + " }\n"); + start_brace(); + } + comprintf("\tdont_care_flags();\n"); + /* Except for the handling of the V flag, this is identical to + LSL. The handling of V is, uhm, unpleasant, so if it's needed, + let the normal emulation handle it. Shoulders of giants kinda + thing ;-) */ + comprintf( + " if (needed_flags & FLAG_V) {\n" + " FAIL(1);\n" + " " RETURN "\n" + " }\n"); + + genamode(curi->smode, "srcreg", curi->size, "cnt", GENA_GETV_FETCH, GENA_MOVEM_DO_INC); + genamode(curi->dmode, "dstreg", curi->size, "data", GENA_GETV_FETCH, GENA_MOVEM_DO_INC); + start_brace(); - comprintf("\tint highmask;\n" - "\tint cdata=scratchie++;\n" - "\tint tmpcnt=scratchie++;\n"); - comprintf("\tmov_l_rr(tmpcnt,cnt);\n" - "\tand_l_ri(tmpcnt,63);\n" - "\tmov_l_ri(cdata,0);\n" - "\tcmov_l_rr(cdata,data,%d);\n",NATIVE_CC_NE); - /* cdata is now either data (for shift count!=0) or - 0 (for shift count==0) */ - switch(curi->size) { - case sz_byte: comprintf("\tshll_b_rr(data,cnt);\n" - "\thighmask=0x38;\n"); - break; - case sz_word: comprintf("\tshll_w_rr(data,cnt);\n" - "\thighmask=0x30;\n"); - break; - case sz_long: comprintf("\tshll_l_rr(data,cnt);\n" - "\thighmask=0x20;\n"); - break; - default: assert(0); - } - comprintf("test_l_ri(cnt,highmask);\n" - "mov_l_ri(scratchie,0);\n" - "cmov_l_rr(scratchie,data,%d);\n",NATIVE_CC_EQ); - switch(curi->size) { - case sz_byte: comprintf("\tmov_b_rr(data,scratchie);\n");break; - case sz_word: comprintf("\tmov_w_rr(data,scratchie);\n");break; - case sz_long: comprintf("\tmov_l_rr(data,scratchie);\n");break; - default: assert(0); - } - /* Result of shift is now in data. Now we need to determine - the carry by shifting cdata one less */ - comprintf("\tsub_l_ri(tmpcnt,1);\n"); - switch(curi->size) { - case sz_byte: comprintf("\tshll_b_rr(cdata,tmpcnt);\n");break; - case sz_word: comprintf("\tshll_w_rr(cdata,tmpcnt);\n");break; - case sz_long: comprintf("\tshll_l_rr(cdata,tmpcnt);\n");break; - default: assert(0); - } - comprintf("test_l_ri(tmpcnt,highmask);\n" - "mov_l_ri(scratchie,0);\n" - "cmov_l_rr(cdata,scratchie,%d);\n",NATIVE_CC_NE); + if (!noflags) + comprintf("\tstart_needflags();\n"); + if (curi->smode != immi) { + uses_cmov; + start_brace(); + comprintf("\tint cdata = scratchie++;\n"); + comprintf("\tint tmpcnt=scratchie++;\n"); + comprintf("\tmov_l_rr(tmpcnt,cnt);\n"); + comprintf("\tand_l_ri(tmpcnt,63);\n"); + comprintf("\tmov_l_ri(cdata, 0);\n"); + switch (curi->size) { + case sz_byte: + comprintf("\ttest_l_ri(tmpcnt, 0x38);\n"); + comprintf("\tcmov_l_rr(cdata, data, NATIVE_CC_EQ);\n"); + comprintf("\tshll_b_rr(cdata,tmpcnt);\n"); + comprintf("\tmov_b_rr(data, cdata);\n"); + break; + case sz_word: + comprintf("\ttest_l_ri(tmpcnt, 0x30);\n"); + comprintf("\tcmov_l_rr(cdata, data, NATIVE_CC_EQ);\n"); + comprintf("\tshll_w_rr(cdata,tmpcnt);\n"); + comprintf("\tmov_w_rr(data, cdata);\n"); + break; + case sz_long: + comprintf("\ttest_l_ri(tmpcnt, 0x20);\n"); + comprintf("\tcmov_l_rr(cdata, data, NATIVE_CC_EQ);\n"); + comprintf("\tshll_l_rr(cdata,tmpcnt);\n"); + comprintf("\tmov_l_rr(data, cdata);\n"); + break; + default: assert(0); + } + /* Result of shift is now in data. */ + } else { + switch (curi->size) { + case sz_byte: comprintf("\tshll_b_ri(data,srcreg);\n"); break; + case sz_word: comprintf("\tshll_w_ri(data,srcreg);\n"); break; + case sz_long: comprintf("\tshll_l_ri(data,srcreg);\n"); break; + default: assert(0); + } + } /* And create the flags */ - comprintf("\tstart_needflags();\n"); - - comprintf("\tif (needed_flags & FLAG_ZNV)\n"); - switch(curi->size) { - case sz_byte: comprintf("\t test_b_rr(data,data);\n"); - comprintf("\t bt_l_ri(cdata,7);\n"); break; - case sz_word: comprintf("\t test_w_rr(data,data);\n"); - comprintf("\t bt_l_ri(cdata,15);\n"); break; - case sz_long: comprintf("\t test_l_rr(data,data);\n"); - comprintf("\t bt_l_ri(cdata,31);\n"); break; - } - comprintf("\t live_flags();\n"); - comprintf("\t end_needflags();\n"); - comprintf("\t duplicate_carry();\n"); - comprintf("if (!(needed_flags & FLAG_CZNV)) dont_care_flags();\n"); - genastore ("data", curi->dmode, "dstreg", curi->size, "data"); - } - else { - uses_cmov; - start_brace(); - comprintf("\tint highmask;\n"); - switch(curi->size) { - case sz_byte: comprintf("\tshll_b_rr(data,cnt);\n" - "\thighmask=0x38;\n"); - break; - case sz_word: comprintf("\tshll_w_rr(data,cnt);\n" - "\thighmask=0x30;\n"); - break; - case sz_long: comprintf("\tshll_l_rr(data,cnt);\n" - "\thighmask=0x20;\n"); - break; - default: assert(0); - } - comprintf("test_l_ri(cnt,highmask);\n" - "mov_l_ri(scratchie,0);\n" - "cmov_l_rr(scratchie,data,%d);\n",NATIVE_CC_EQ); - switch(curi->size) { - case sz_byte: comprintf("\tmov_b_rr(data,scratchie);\n");break; - case sz_word: comprintf("\tmov_w_rr(data,scratchie);\n");break; - case sz_long: comprintf("\tmov_l_rr(data,scratchie);\n");break; - default: assert(0); - } - genastore ("data", curi->dmode, "dstreg", curi->size, "data"); - } - } - else { - start_brace(); - comprintf("\tint tmp=scratchie++;\n" - "\tint bp;\n" - "\tmov_l_rr(tmp,data);\n"); - switch(curi->size) { - case sz_byte: comprintf("\tshll_b_ri(data,srcreg);\n" - "\tbp=8-srcreg;\n"); break; - case sz_word: comprintf("\tshll_w_ri(data,srcreg);\n" - "\tbp=16-srcreg;\n"); break; - case sz_long: comprintf("\tshll_l_ri(data,srcreg);\n" - "\tbp=32-srcreg;\n"); break; - default: assert(0); - } - - if (!noflags) { - comprintf("\tstart_needflags();\n"); - comprintf("\tif (needed_flags & FLAG_ZNV)\n"); - switch(curi->size) { - case sz_byte: comprintf("\t test_b_rr(data,data);\n"); break; - case sz_word: comprintf("\t test_w_rr(data,data);\n"); break; - case sz_long: comprintf("\t test_l_rr(data,data);\n"); break; - } - comprintf("\t bt_l_ri(tmp,bp);\n"); /* Set C */ - comprintf("\t live_flags();\n"); - comprintf("\t end_needflags();\n"); - comprintf("\t duplicate_carry();\n"); - comprintf("if (!(needed_flags & FLAG_CZNV)) dont_care_flags();\n"); - } - genastore ("data", curi->dmode, "dstreg", curi->size, "data"); - } - break; + if (!noflags) { + comprintf("\tlive_flags();\n"); + comprintf("\tend_needflags();\n"); + if (curi->smode != immi) + comprintf("\tsetcc_for_cntzero(tmpcnt, data, %d);\n", curi->size == sz_byte ? 1 : curi->size == sz_word ? 2 : 4); + else + comprintf("\tduplicate_carry();\n"); + comprintf("if (!(needed_flags & FLAG_CZNV)) dont_care_flags();\n"); + } + genastore("data", curi->dmode, "dstreg", curi->size, "data"); + break; - case i_LSR: + case i_LSR: #ifdef DISABLE_I_LSR - failure; -#endif - mayfail; - if (curi->smode==Dreg) { - comprintf("if ((uae_u32)srcreg==(uae_u32)dstreg) {\n" - " FAIL(1);\n" - " " RETURN "\n" - "} \n"); - start_brace(); - } - comprintf("\tdont_care_flags();\n"); + failure; +#endif + mayfail; + if (curi->smode == Dreg) { + comprintf( + " if ((uae_u32)srcreg==(uae_u32)dstreg) {\n" + " FAIL(1);\n" + " " RETURN "\n" + " }\n"); + start_brace(); + } + comprintf("\tdont_care_flags();\n"); + + genamode(curi->smode, "srcreg", curi->size, "cnt", GENA_GETV_FETCH, GENA_MOVEM_DO_INC); + genamode(curi->dmode, "dstreg", curi->size, "data", GENA_GETV_FETCH, GENA_MOVEM_DO_INC); - genamode (curi->smode, "srcreg", curi->size, "cnt", 1, 0); - genamode (curi->dmode, "dstreg", curi->size, "data", 1, 0); - if (curi->smode!=immi) { - if (!noflags) { - uses_cmov; start_brace(); - comprintf("\tint highmask;\n" - "\tint cdata=scratchie++;\n" - "\tint tmpcnt=scratchie++;\n"); - comprintf("\tmov_l_rr(tmpcnt,cnt);\n" - "\tand_l_ri(tmpcnt,63);\n" - "\tmov_l_ri(cdata,0);\n" - "\tcmov_l_rr(cdata,data,%d);\n",NATIVE_CC_NE); - /* cdata is now either data (for shift count!=0) or - 0 (for shift count==0) */ - switch(curi->size) { - case sz_byte: comprintf("\tshrl_b_rr(data,cnt);\n" - "\thighmask=0x38;\n"); - break; - case sz_word: comprintf("\tshrl_w_rr(data,cnt);\n" - "\thighmask=0x30;\n"); - break; - case sz_long: comprintf("\tshrl_l_rr(data,cnt);\n" - "\thighmask=0x20;\n"); - break; - default: assert(0); - } - comprintf("test_l_ri(cnt,highmask);\n" - "mov_l_ri(scratchie,0);\n" - "cmov_l_rr(scratchie,data,%d);\n",NATIVE_CC_EQ); - switch(curi->size) { - case sz_byte: comprintf("\tmov_b_rr(data,scratchie);\n");break; - case sz_word: comprintf("\tmov_w_rr(data,scratchie);\n");break; - case sz_long: comprintf("\tmov_l_rr(data,scratchie);\n");break; - default: assert(0); - } - /* Result of shift is now in data. Now we need to determine - the carry by shifting cdata one less */ - comprintf("\tsub_l_ri(tmpcnt,1);\n"); - switch(curi->size) { - case sz_byte: comprintf("\tshrl_b_rr(cdata,tmpcnt);\n");break; - case sz_word: comprintf("\tshrl_w_rr(cdata,tmpcnt);\n");break; - case sz_long: comprintf("\tshrl_l_rr(cdata,tmpcnt);\n");break; - default: assert(0); - } - comprintf("test_l_ri(tmpcnt,highmask);\n" - "mov_l_ri(scratchie,0);\n" - "cmov_l_rr(cdata,scratchie,%d);\n",NATIVE_CC_NE); + if (!noflags) + comprintf("\tstart_needflags();\n"); + if (curi->smode != immi) { + uses_cmov; + start_brace(); + comprintf("\tint cdata = scratchie++;\n"); + comprintf("\tint tmpcnt=scratchie++;\n"); + comprintf("\tmov_l_rr(tmpcnt,cnt);\n"); + comprintf("\tand_l_ri(tmpcnt,63);\n"); + comprintf("\tmov_l_ri(cdata, 0);\n"); + switch (curi->size) { + case sz_byte: + comprintf("\ttest_l_ri(tmpcnt, 0x38);\n"); + comprintf("\tcmov_l_rr(cdata, data, NATIVE_CC_EQ);\n"); + comprintf("\tshrl_b_rr(cdata,tmpcnt);\n"); + comprintf("\tmov_b_rr(data, cdata);\n"); + break; + case sz_word: + comprintf("\ttest_l_ri(tmpcnt, 0x30);\n"); + comprintf("\tcmov_l_rr(cdata, data, NATIVE_CC_EQ);\n"); + comprintf("\tshrl_w_rr(cdata,tmpcnt);\n"); + comprintf("\tmov_w_rr(data, cdata);\n"); + break; + case sz_long: + comprintf("\ttest_l_ri(tmpcnt, 0x20);\n"); + comprintf("\tcmov_l_rr(cdata, data, NATIVE_CC_EQ);\n"); + comprintf("\tshrl_l_rr(cdata, tmpcnt);\n"); + comprintf("\tmov_l_rr(data, cdata);\n"); + break; + default: assert(0); + } + /* Result of shift is now in data. */ + } else { + switch (curi->size) { + case sz_byte: comprintf("\tshrl_b_ri(data,srcreg);\n"); break; + case sz_word: comprintf("\tshrl_w_ri(data,srcreg);\n"); break; + case sz_long: comprintf("\tshrl_l_ri(data,srcreg);\n"); break; + default: assert(0); + } + } /* And create the flags */ - comprintf("\tstart_needflags();\n"); - comprintf("\tif (needed_flags & FLAG_ZNV)\n"); - switch(curi->size) { - case sz_byte: comprintf("\t test_b_rr(data,data);\n"); break; - case sz_word: comprintf("\t test_w_rr(data,data);\n"); break; - case sz_long: comprintf("\t test_l_rr(data,data);\n"); break; - } - comprintf("\t bt_l_ri(cdata,0);\n"); /* Set C */ - comprintf("\t live_flags();\n"); - comprintf("\t end_needflags();\n"); - comprintf("\t duplicate_carry();\n"); - comprintf("if (!(needed_flags & FLAG_CZNV)) dont_care_flags();\n"); - genastore ("data", curi->dmode, "dstreg", curi->size, "data"); - } - else { - uses_cmov; - start_brace(); - comprintf("\tint highmask;\n"); - switch(curi->size) { - case sz_byte: comprintf("\tshrl_b_rr(data,cnt);\n" - "\thighmask=0x38;\n"); - break; - case sz_word: comprintf("\tshrl_w_rr(data,cnt);\n" - "\thighmask=0x30;\n"); - break; - case sz_long: comprintf("\tshrl_l_rr(data,cnt);\n" - "\thighmask=0x20;\n"); - break; - default: assert(0); - } - comprintf("test_l_ri(cnt,highmask);\n" - "mov_l_ri(scratchie,0);\n" - "cmov_l_rr(scratchie,data,%d);\n",NATIVE_CC_EQ); - switch(curi->size) { - case sz_byte: comprintf("\tmov_b_rr(data,scratchie);\n");break; - case sz_word: comprintf("\tmov_w_rr(data,scratchie);\n");break; - case sz_long: comprintf("\tmov_l_rr(data,scratchie);\n");break; - default: assert(0); - } - genastore ("data", curi->dmode, "dstreg", curi->size, "data"); - } - } - else { - start_brace(); - comprintf("\tint tmp=scratchie++;\n" - "\tint bp;\n" - "\tmov_l_rr(tmp,data);\n"); - switch(curi->size) { - case sz_byte: comprintf("\tshrl_b_ri(data,srcreg);\n" - "\tbp=srcreg-1;\n"); break; - case sz_word: comprintf("\tshrl_w_ri(data,srcreg);\n" - "\tbp=srcreg-1;\n"); break; - case sz_long: comprintf("\tshrl_l_ri(data,srcreg);\n" - "\tbp=srcreg-1;\n"); break; - default: assert(0); - } - - if (!noflags) { - comprintf("\tstart_needflags();\n"); - comprintf("\tif (needed_flags & FLAG_ZNV)\n"); - switch(curi->size) { - case sz_byte: comprintf("\t test_b_rr(data,data);\n"); break; - case sz_word: comprintf("\t test_w_rr(data,data);\n"); break; - case sz_long: comprintf("\t test_l_rr(data,data);\n"); break; - } - comprintf("\t bt_l_ri(tmp,bp);\n"); /* Set C */ - comprintf("\t live_flags();\n"); - comprintf("\t end_needflags();\n"); - comprintf("\t duplicate_carry();\n"); - comprintf("if (!(needed_flags & FLAG_CZNV)) dont_care_flags();\n"); - } - genastore ("data", curi->dmode, "dstreg", curi->size, "data"); - } - break; + if (!noflags) { + comprintf("\tlive_flags();\n"); + comprintf("\tend_needflags();\n"); + if (curi->smode != immi) + comprintf("\tsetcc_for_cntzero(tmpcnt, data, %d);\n", curi->size == sz_byte ? 1 : curi->size == sz_word ? 2 : 4); + else + comprintf("\tduplicate_carry();\n"); + comprintf("if (!(needed_flags & FLAG_CZNV)) dont_care_flags();\n"); + } + genastore("data", curi->dmode, "dstreg", curi->size, "data"); + break; - case i_LSL: + case i_LSL: #ifdef DISABLE_I_LSL - failure; -#endif - mayfail; - if (curi->smode==Dreg) { - comprintf("if ((uae_u32)srcreg==(uae_u32)dstreg) {\n" - " FAIL(1);\n" - " " RETURN "\n" - "} \n"); - start_brace(); - } - comprintf("\tdont_care_flags();\n"); + failure; +#endif + mayfail; + if (curi->smode == Dreg) { + comprintf( + " if ((uae_u32)srcreg==(uae_u32)dstreg) {\n" + " FAIL(1);\n" + " " RETURN "\n" + " }\n"); + start_brace(); + } + comprintf("\tdont_care_flags();\n"); + + genamode(curi->smode, "srcreg", curi->size, "cnt", GENA_GETV_FETCH, GENA_MOVEM_DO_INC); + genamode(curi->dmode, "dstreg", curi->size, "data", GENA_GETV_FETCH, GENA_MOVEM_DO_INC); - genamode (curi->smode, "srcreg", curi->size, "cnt", 1, 0); - genamode (curi->dmode, "dstreg", curi->size, "data", 1, 0); - if (curi->smode!=immi) { - if (!noflags) { - uses_cmov; start_brace(); - comprintf("\tint highmask;\n" - "\tint cdata=scratchie++;\n" - "\tint tmpcnt=scratchie++;\n"); - comprintf("\tmov_l_rr(tmpcnt,cnt);\n" - "\tand_l_ri(tmpcnt,63);\n" - "\tmov_l_ri(cdata,0);\n" - "\tcmov_l_rr(cdata,data,%d);\n",NATIVE_CC_NE); - /* cdata is now either data (for shift count!=0) or - 0 (for shift count==0) */ - switch(curi->size) { - case sz_byte: comprintf("\tshll_b_rr(data,cnt);\n" - "\thighmask=0x38;\n"); - break; - case sz_word: comprintf("\tshll_w_rr(data,cnt);\n" - "\thighmask=0x30;\n"); - break; - case sz_long: comprintf("\tshll_l_rr(data,cnt);\n" - "\thighmask=0x20;\n"); - break; - default: assert(0); - } - comprintf("test_l_ri(cnt,highmask);\n" - "mov_l_ri(scratchie,0);\n" - "cmov_l_rr(scratchie,data,%d);\n",NATIVE_CC_EQ); - switch(curi->size) { - case sz_byte: comprintf("\tmov_b_rr(data,scratchie);\n");break; - case sz_word: comprintf("\tmov_w_rr(data,scratchie);\n");break; - case sz_long: comprintf("\tmov_l_rr(data,scratchie);\n");break; - default: assert(0); - } - /* Result of shift is now in data. Now we need to determine - the carry by shifting cdata one less */ - comprintf("\tsub_l_ri(tmpcnt,1);\n"); - switch(curi->size) { - case sz_byte: comprintf("\tshll_b_rr(cdata,tmpcnt);\n");break; - case sz_word: comprintf("\tshll_w_rr(cdata,tmpcnt);\n");break; - case sz_long: comprintf("\tshll_l_rr(cdata,tmpcnt);\n");break; - default: assert(0); - } - comprintf("test_l_ri(tmpcnt,highmask);\n" - "mov_l_ri(scratchie,0);\n" - "cmov_l_rr(cdata,scratchie,%d);\n",NATIVE_CC_NE); + if (!noflags) + comprintf("\tstart_needflags();\n"); + if (curi->smode != immi) { + uses_cmov; + start_brace(); + comprintf("\tint cdata = scratchie++;\n"); + comprintf("\tint tmpcnt = scratchie++;\n"); + comprintf("\tmov_l_rr(tmpcnt,cnt);\n"); + comprintf("\tand_l_ri(tmpcnt,63);\n"); + comprintf("\tmov_l_ri(cdata, 0);\n"); + switch (curi->size) { + case sz_byte: + comprintf("\ttest_l_ri(tmpcnt, 0x38);\n"); + comprintf("\tcmov_l_rr(cdata, data, NATIVE_CC_EQ);\n"); + comprintf("\tshll_b_rr(cdata,tmpcnt);\n"); + comprintf("\tmov_b_rr(data, cdata);\n"); + break; + case sz_word: + comprintf("\ttest_l_ri(tmpcnt, 0x30);\n"); + comprintf("\tcmov_l_rr(cdata, data, NATIVE_CC_EQ);\n"); + comprintf("\tshll_w_rr(cdata,tmpcnt);\n"); + comprintf("\tmov_w_rr(data, cdata);\n"); + break; + case sz_long: + comprintf("\ttest_l_ri(tmpcnt, 0x20);\n"); + comprintf("\tcmov_l_rr(cdata, data, NATIVE_CC_EQ);\n"); + comprintf("\tshll_l_rr(cdata,tmpcnt);\n"); + comprintf("\tmov_l_rr(data, cdata);\n"); + break; + default: assert(0); + } + /* Result of shift is now in data. */ + } else { + switch (curi->size) { + case sz_byte: comprintf("\tshll_b_ri(data,srcreg);\n"); break; + case sz_word: comprintf("\tshll_w_ri(data,srcreg);\n"); break; + case sz_long: comprintf("\tshll_l_ri(data,srcreg);\n"); break; + default: assert(0); + } + } /* And create the flags */ - comprintf("\tstart_needflags();\n"); - comprintf("\tif (needed_flags & FLAG_ZNV)\n"); - switch(curi->size) { - case sz_byte: comprintf("\t test_b_rr(data,data);\n"); - comprintf("\t bt_l_ri(cdata,7);\n"); break; - case sz_word: comprintf("\t test_w_rr(data,data);\n"); - comprintf("\t bt_l_ri(cdata,15);\n"); break; - case sz_long: comprintf("\t test_l_rr(data,data);\n"); - comprintf("\t bt_l_ri(cdata,31);\n"); break; - } - comprintf("\t live_flags();\n"); - comprintf("\t end_needflags();\n"); - comprintf("\t duplicate_carry();\n"); - comprintf("if (!(needed_flags & FLAG_CZNV)) dont_care_flags();\n"); - genastore ("data", curi->dmode, "dstreg", curi->size, "data"); - } - else { - uses_cmov; - start_brace(); - comprintf("\tint highmask;\n"); - switch(curi->size) { - case sz_byte: comprintf("\tshll_b_rr(data,cnt);\n" - "\thighmask=0x38;\n"); - break; - case sz_word: comprintf("\tshll_w_rr(data,cnt);\n" - "\thighmask=0x30;\n"); - break; - case sz_long: comprintf("\tshll_l_rr(data,cnt);\n" - "\thighmask=0x20;\n"); - break; - default: assert(0); - } - comprintf("test_l_ri(cnt,highmask);\n" - "mov_l_ri(scratchie,0);\n" - "cmov_l_rr(scratchie,data,%d);\n",NATIVE_CC_EQ); - switch(curi->size) { - case sz_byte: comprintf("\tmov_b_rr(data,scratchie);\n");break; - case sz_word: comprintf("\tmov_w_rr(data,scratchie);\n");break; - case sz_long: comprintf("\tmov_l_rr(data,scratchie);\n");break; - default: assert(0); - } - genastore ("data", curi->dmode, "dstreg", curi->size, "data"); - } - } - else { - start_brace(); - comprintf("\tint tmp=scratchie++;\n" - "\tint bp;\n" - "\tmov_l_rr(tmp,data);\n"); - switch(curi->size) { - case sz_byte: comprintf("\tshll_b_ri(data,srcreg);\n" - "\tbp=8-srcreg;\n"); break; - case sz_word: comprintf("\tshll_w_ri(data,srcreg);\n" - "\tbp=16-srcreg;\n"); break; - case sz_long: comprintf("\tshll_l_ri(data,srcreg);\n" - "\tbp=32-srcreg;\n"); break; - default: assert(0); - } - - if (!noflags) { - comprintf("\tstart_needflags();\n"); - comprintf("\tif (needed_flags & FLAG_ZNV)\n"); - switch(curi->size) { - case sz_byte: comprintf("\t test_b_rr(data,data);\n"); break; - case sz_word: comprintf("\t test_w_rr(data,data);\n"); break; - case sz_long: comprintf("\t test_l_rr(data,data);\n"); break; - } - comprintf("\t bt_l_ri(tmp,bp);\n"); /* Set C */ - comprintf("\t live_flags();\n"); - comprintf("\t end_needflags();\n"); - comprintf("\t duplicate_carry();\n"); - comprintf("if (!(needed_flags & FLAG_CZNV)) dont_care_flags();\n"); - } - genastore ("data", curi->dmode, "dstreg", curi->size, "data"); - } - break; + if (!noflags) { + comprintf("\tlive_flags();\n"); + comprintf("\tend_needflags();\n"); + if (curi->smode != immi) + comprintf("\tsetcc_for_cntzero(tmpcnt, data, %d);\n", curi->size == sz_byte ? 1 : curi->size == sz_word ? 2 : 4); + else + comprintf("\tduplicate_carry();\n"); + comprintf("if (!(needed_flags & FLAG_CZNV)) dont_care_flags();\n"); + } + genastore("data", curi->dmode, "dstreg", curi->size, "data"); + break; - case i_ROL: + case i_ROL: #ifdef DISABLE_I_ROL - failure; -#endif - mayfail; - if (curi->smode==Dreg) { - comprintf("if ((uae_u32)srcreg==(uae_u32)dstreg) {\n" - " FAIL(1);\n" - " " RETURN "\n" - "} \n"); - start_brace(); - } - comprintf("\tdont_care_flags();\n"); - genamode (curi->smode, "srcreg", curi->size, "cnt", 1, 0); - genamode (curi->dmode, "dstreg", curi->size, "data", 1, 0); - start_brace (); - - switch(curi->size) { - case sz_long: comprintf("\t rol_l_rr(data,cnt);\n"); break; - case sz_word: comprintf("\t rol_w_rr(data,cnt);\n"); break; - case sz_byte: comprintf("\t rol_b_rr(data,cnt);\n"); break; - } + failure; +#endif + mayfail; + if (curi->smode == Dreg) { + comprintf( + " if ((uae_u32)srcreg==(uae_u32)dstreg) {\n" + " FAIL(1);\n" + " " RETURN "\n" + " }\n"); + start_brace(); + } + comprintf("\tdont_care_flags();\n"); + genamode(curi->smode, "srcreg", curi->size, "cnt", GENA_GETV_FETCH, GENA_MOVEM_DO_INC); + genamode(curi->dmode, "dstreg", curi->size, "data", GENA_GETV_FETCH, GENA_MOVEM_DO_INC); + start_brace(); - if (!noflags) { - comprintf("\tstart_needflags();\n"); - comprintf("\tif (needed_flags & FLAG_ZNV)\n"); - switch(curi->size) { - case sz_byte: comprintf("\t test_b_rr(data,data);\n"); break; - case sz_word: comprintf("\t test_w_rr(data,data);\n"); break; - case sz_long: comprintf("\t test_l_rr(data,data);\n"); break; - } - comprintf("\t bt_l_ri(data,0x00);\n"); /* Set C */ - comprintf("\t live_flags();\n"); - comprintf("\t end_needflags();\n"); - } - genastore ("data", curi->dmode, "dstreg", curi->size, "data"); - break; + switch (curi->size) { + case sz_long: comprintf("\trol_l_rr(data,cnt);\n"); break; + case sz_word: comprintf("\trol_w_rr(data,cnt);\n"); break; + case sz_byte: comprintf("\trol_b_rr(data,cnt);\n"); break; + } + + if (!noflags) { + comprintf("\tstart_needflags();\n"); + /* + * x86 ROL instruction does not set ZF/SF, so we need extra checks here + */ + comprintf("\tif (needed_flags & FLAG_ZNV)\n"); + switch (curi->size) { + case sz_byte: comprintf("\t test_b_rr(data,data);\n"); break; + case sz_word: comprintf("\t test_w_rr(data,data);\n"); break; + case sz_long: comprintf("\t test_l_rr(data,data);\n"); break; + } + comprintf("\tbt_l_ri(data,0x00);\n"); /* Set C */ + comprintf("\tlive_flags();\n"); + comprintf("\tend_needflags();\n"); + } + genastore("data", curi->dmode, "dstreg", curi->size, "data"); + break; - case i_ROR: + case i_ROR: #ifdef DISABLE_I_ROR - failure; -#endif - mayfail; - if (curi->smode==Dreg) { - comprintf("if ((uae_u32)srcreg==(uae_u32)dstreg) {\n" - " FAIL(1);\n" - " " RETURN "\n" - "} \n"); - start_brace(); - } - comprintf("\tdont_care_flags();\n"); - genamode (curi->smode, "srcreg", curi->size, "cnt", 1, 0); - genamode (curi->dmode, "dstreg", curi->size, "data", 1, 0); - start_brace (); - - switch(curi->size) { - case sz_long: comprintf("\t ror_l_rr(data,cnt);\n"); break; - case sz_word: comprintf("\t ror_w_rr(data,cnt);\n"); break; - case sz_byte: comprintf("\t ror_b_rr(data,cnt);\n"); break; - } + failure; +#endif + mayfail; + if (curi->smode == Dreg) { + comprintf( + " if ((uae_u32)srcreg==(uae_u32)dstreg) {\n" + " FAIL(1);\n" + " " RETURN "\n" + " }\n"); + start_brace(); + } + comprintf("\tdont_care_flags();\n"); + genamode(curi->smode, "srcreg", curi->size, "cnt", GENA_GETV_FETCH, GENA_MOVEM_DO_INC); + genamode(curi->dmode, "dstreg", curi->size, "data", GENA_GETV_FETCH, GENA_MOVEM_DO_INC); + start_brace(); - if (!noflags) { - comprintf("\tstart_needflags();\n"); - comprintf("\tif (needed_flags & FLAG_ZNV)\n"); - switch(curi->size) { - case sz_byte: comprintf("\t test_b_rr(data,data);\n"); break; - case sz_word: comprintf("\t test_w_rr(data,data);\n"); break; - case sz_long: comprintf("\t test_l_rr(data,data);\n"); break; - } - switch(curi->size) { - case sz_byte: comprintf("\t bt_l_ri(data,0x07);\n"); break; - case sz_word: comprintf("\t bt_l_ri(data,0x0f);\n"); break; - case sz_long: comprintf("\t bt_l_ri(data,0x1f);\n"); break; - } - comprintf("\t live_flags();\n"); - comprintf("\t end_needflags();\n"); - } - genastore ("data", curi->dmode, "dstreg", curi->size, "data"); - break; + switch (curi->size) { + case sz_long: comprintf("\tror_l_rr(data,cnt);\n"); break; + case sz_word: comprintf("\tror_w_rr(data,cnt);\n"); break; + case sz_byte: comprintf("\tror_b_rr(data,cnt);\n"); break; + } - case i_ROXL: - failure; - break; + if (!noflags) { + comprintf("\tstart_needflags();\n"); + /* + * x86 ROR instruction does not set ZF/SF, so we need extra checks here + */ + comprintf("\tif (needed_flags & FLAG_ZNV)\n"); + switch (curi->size) { + case sz_byte: comprintf("\t test_b_rr(data,data);\n"); break; + case sz_word: comprintf("\t test_w_rr(data,data);\n"); break; + case sz_long: comprintf("\t test_l_rr(data,data);\n"); break; + } + switch (curi->size) { + case sz_byte: comprintf("\tbt_l_ri(data,0x07);\n"); break; + case sz_word: comprintf("\tbt_l_ri(data,0x0f);\n"); break; + case sz_long: comprintf("\tbt_l_ri(data,0x1f);\n"); break; + } + comprintf("\tlive_flags();\n"); + comprintf("\tend_needflags();\n"); + } + genastore("data", curi->dmode, "dstreg", curi->size, "data"); + break; - case i_ROXR: - failure; - break; + case i_ROXL: + failure; + break; - case i_ASRW: - failure; - break; + case i_ROXR: + failure; + break; - case i_ASLW: - failure; - break; + case i_ASRW: + failure; + break; - case i_LSRW: - failure; - break; + case i_ASLW: + failure; + break; - case i_LSLW: - failure; - break; + case i_LSRW: + failure; + break; - case i_ROLW: - failure; - break; + case i_LSLW: + failure; + break; - case i_RORW: - failure; - break; + case i_ROLW: + failure; + break; - case i_ROXLW: - failure; - break; + case i_RORW: + failure; + break; - case i_ROXRW: - failure; - break; + case i_ROXLW: + failure; + break; - case i_MOVEC2: - isjump; - failure; - break; + case i_ROXRW: + failure; + break; - case i_MOVE2C: - isjump; - failure; - break; + case i_MOVEC2: + isjump; + failure; + break; - case i_CAS: - failure; - break; + case i_MOVE2C: + isjump; + failure; + break; - case i_CAS2: - failure; - break; + case i_CAS: + failure; + break; - case i_MOVES: /* ignore DFC and SFC because we have no MMU */ - isjump; - failure; - break; + case i_CAS2: + failure; + break; - case i_BKPT: /* only needed for hardware emulators */ - isjump; - failure; - break; + case i_MOVES: /* ignore DFC and SFC because we have no MMU */ + isjump; + failure; + break; - case i_CALLM: /* not present in 68030 */ - isjump; - failure; - break; + case i_BKPT: /* only needed for hardware emulators */ + isjump; + failure; + break; - case i_RTM: /* not present in 68030 */ - isjump; - failure; - break; + case i_CALLM: /* not present in 68030 */ + isjump; + failure; + break; - case i_TRAPcc: - isjump; - failure; - break; + case i_RTM: /* not present in 68030 */ + isjump; + failure; + break; - case i_DIVL: - isjump; - failure; - break; + case i_TRAPcc: + isjump; + failure; + break; - case i_MULL: + case i_DIVL: + isjump; + failure; + break; + + case i_MULL: #ifdef DISABLE_I_MULL - failure; + failure; #endif - if (!noflags) { - failure; - break; - } - comprintf("\tuae_u16 extra=%s;\n",gen_nextiword()); - comprintf("\tint r2=(extra>>12)&7;\n" - "\tint tmp=scratchie++;\n"); - - genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0); - /* The two operands are in dst and r2 */ - comprintf("\tif (extra&0x0400) {\n" /* Need full 64 bit result */ - "\tint r3=(extra&7);\n" - "\tmov_l_rr(r3,dst);\n"); /* operands now in r3 and r2 */ - comprintf("\tif (extra&0x0800) { \n" /* signed */ - "\t\timul_64_32(r2,r3);\n" - "\t} else { \n" - "\t\tmul_64_32(r2,r3);\n" - "\t} \n"); - /* The result is in r2/tmp, with r2 holding the lower 32 bits */ - comprintf("\t} else {\n"); /* Only want 32 bit result */ - /* operands in dst and r2, result foes into r2 */ - /* shouldn't matter whether it's signed or unsigned?!? */ - comprintf("\timul_32_32(r2,dst);\n" - "\t}\n"); - break; + if (!noflags) { + failure; + break; + } + comprintf("\tuae_u16 extra=%s;\n", gen_nextiword()); + comprintf("\tint r2=(extra>>12)&7;\n" + "\tint tmp=scratchie++;\n"); + + genamode(curi->dmode, "dstreg", curi->size, "dst", GENA_GETV_FETCH, GENA_MOVEM_DO_INC); + /* The two operands are in dst and r2 */ + comprintf("\tif (extra&0x0400) {\n" /* Need full 64 bit result */ + "\tint r3=(extra&7);\n" + "\tmov_l_rr(r3,dst);\n"); /* operands now in r3 and r2 */ + comprintf("\tif (extra&0x0800) { \n" /* signed */ + "\t\timul_64_32(r2,r3);\n" + "\t} else { \n" + "\t\tmul_64_32(r2,r3);\n" + "\t} \n"); + /* The result is in r2/tmp, with r2 holding the lower 32 bits */ + comprintf("\t} else {\n"); /* Only want 32 bit result */ + /* operands in dst and r2, result foes into r2 */ + /* shouldn't matter whether it's signed or unsigned?!? */ + comprintf("\timul_32_32(r2,dst);\n" + "\t}\n"); + break; - case i_BFTST: - case i_BFEXTU: - case i_BFCHG: - case i_BFEXTS: - case i_BFCLR: - case i_BFFFO: - case i_BFSET: - case i_BFINS: - failure; - break; + case i_BFTST: + case i_BFEXTU: + case i_BFCHG: + case i_BFEXTS: + case i_BFCLR: + case i_BFFFO: + case i_BFSET: + case i_BFINS: + failure; + break; - case i_PACK: - failure; - break; + case i_PACK: + failure; + break; - case i_UNPK: - failure; - break; + case i_UNPK: + failure; + break; - case i_TAS: - failure; - break; + case i_TAS: + failure; + break; - case i_FPP: + case i_FPP: #ifdef DISABLE_I_FPP - failure; -#endif - uses_fpu; - mayfail; - comprintf("#ifdef USE_JIT_FPU\n"); - comprintf("\tuae_u16 extra=%s;\n",gen_nextiword()); - swap_opcode(); - comprintf("\tcomp_fpp_opp(opcode,extra);\n"); - comprintf("#else\n"); - comprintf("\tfailure = 1;\n"); - comprintf("#endif\n"); - break; + failure; +#endif + uses_fpu; + mayfail; + comprintf("#ifdef USE_JIT_FPU\n"); + comprintf("\tuae_u16 extra=%s;\n", gen_nextiword()); + swap_opcode(); + comprintf("\tcomp_fpp_opp(opcode,extra);\n"); + comprintf("#else\n"); + comprintf("\tfailure = 1;\n"); + comprintf("#endif\n"); + break; - case i_FBcc: + case i_FBcc: #ifdef DISABLE_I_FBCC - failure; + failure; #endif - uses_fpu; - isjump; - uses_cmov; - mayfail; - comprintf("#ifdef USE_JIT_FPU\n"); - swap_opcode(); - comprintf("\tcomp_fbcc_opp(opcode);\n"); - comprintf("#else\n"); - comprintf("\tfailure = 1;\n"); - comprintf("#endif\n"); - break; + uses_fpu; + isjump; + uses_cmov; + mayfail; + comprintf("#ifdef USE_JIT_FPU\n"); + swap_opcode(); + comprintf("\tcomp_fbcc_opp(opcode);\n"); + comprintf("#else\n"); + comprintf("\tfailure = 1;\n"); + comprintf("#endif\n"); + break; - case i_FDBcc: - uses_fpu; - isjump; - failure; - break; + case i_FDBcc: + uses_fpu; + isjump; + failure; + break; - case i_FScc: + case i_FScc: #ifdef DISABLE_I_FSCC - failure; + failure; #endif - uses_fpu; - mayfail; - uses_cmov; - comprintf("#ifdef USE_JIT_FPU\n"); - comprintf("\tuae_u16 extra=%s;\n",gen_nextiword()); - swap_opcode(); - comprintf("\tcomp_fscc_opp(opcode,extra);\n"); - comprintf("#else\n"); - comprintf("\tfailure = 1;\n"); - comprintf("#endif\n"); - break; + uses_fpu; + mayfail; + uses_cmov; + comprintf("#ifdef USE_JIT_FPU\n"); + comprintf("\tuae_u16 extra=%s;\n", gen_nextiword()); + swap_opcode(); + comprintf("\tcomp_fscc_opp(opcode,extra);\n"); + comprintf("#else\n"); + comprintf("\tfailure = 1;\n"); + comprintf("#endif\n"); + break; - case i_FTRAPcc: - uses_fpu; - isjump; - failure; - break; + case i_FTRAPcc: + uses_fpu; + isjump; + failure; + break; - case i_FSAVE: - uses_fpu; - failure; - break; + case i_FSAVE: + uses_fpu; + failure; + break; - case i_FRESTORE: - uses_fpu; - failure; - break; + case i_FRESTORE: + uses_fpu; + failure; + break; - case i_CINVL: - case i_CINVP: - case i_CINVA: - isjump; /* Not really, but it's probably a good idea to stop - translating at this point */ - failure; - comprintf ("\tflush_icache();\n"); /* Differentiate a bit more? */ - break; + case i_CINVL: + case i_CINVP: + case i_CINVA: + isjump; /* Not really, but it's probably a good idea to stop + translating at this point */ + failure; + comprintf("\tflush_icache();\n"); /* Differentiate a bit more? */ + break; - case i_CPUSHL: - case i_CPUSHP: - case i_CPUSHA: - isjump; /* Not really, but it's probably a good idea to stop - translating at this point */ - failure; - break; + case i_CPUSHL: + case i_CPUSHP: + case i_CPUSHA: + isjump; /* Not really, but it's probably a good idea to stop + translating at this point */ + failure; + break; - case i_MOVE16: + case i_MOVE16: #ifdef DISABLE_I_MOVE16 - failure; + failure; #endif - genmov16(opcode,curi); - break; + genmov16(opcode, curi); + break; #ifdef UAE - case i_MMUOP030: - case i_PFLUSHN: - case i_PFLUSH: - case i_PFLUSHAN: - case i_PFLUSHA: - case i_PLPAR: - case i_PLPAW: - case i_PTESTR: - case i_PTESTW: - case i_LPSTOP: - case i_HALT: - case i_PULSE: - isjump; - failure; - break; + case i_MMUOP030: + case i_PFLUSHN: + case i_PFLUSH: + case i_PFLUSHAN: + case i_PFLUSHA: + case i_PLPAR: + case i_PLPAW: + case i_PTESTR: + case i_PTESTW: + case i_LPSTOP: + case i_PULSE: + case i_HALT: + isjump; + failure; + break; #endif #ifdef WINUAE_ARANYM - case i_EMULOP_RETURN: - isjump; - failure; - break; - - case i_EMULOP: - failure; - break; + case i_EMULOP_RETURN: + isjump; + failure; + break; - case i_NATFEAT_ID: - case i_NATFEAT_CALL: - failure; - break; + case i_EMULOP: + failure; + break; - case i_MMUOP: - isjump; - failure; - break; + case i_NATFEAT_ID: + case i_NATFEAT_CALL: + failure; + break; + + case i_MMUOP: + isjump; + failure; + break; #endif - default: + default: assert(0); - break; - } - comprintf("%s",endstr); - finish_braces (); - sync_m68k_pc (); - if (global_mayfail) - comprintf("\tif (failure) m68k_pc_offset=m68k_pc_offset_thisinst;\n"); - return global_failure; + break; + } + comprintf("%s", endstr); + finish_braces(); + sync_m68k_pc(); + if (global_mayfail) { + comprintf("if (failure) {\n"); + comprintf("m68k_pc_offset = m68k_pc_offset_thisinst;\n"); + comprintf("}\n"); + } + return global_failure; } static void -generate_includes (FILE * f) +generate_includes(FILE *f) { - fprintf (f, "#include \"sysconfig.h\"\n"); - fprintf (f, "#if defined(JIT)\n"); - fprintf (f, "#include \"sysdeps.h\"\n"); + fprintf(f, "#include \"sysconfig.h\"\n"); + fprintf(f, "#if defined(JIT)\n"); + fprintf(f, "#include \"sysdeps.h\"\n"); #ifdef UAE - fprintf (f, "#include \"options.h\"\n"); - fprintf (f, "#include \"memory.h\"\n"); + fprintf(f, "#include \"options.h\"\n"); + fprintf(f, "#include \"uae/memory.h\"\n"); #else - fprintf (f, "#include \"m68k.h\"\n"); - fprintf (f, "#include \"memory-uae.h\"\n"); + fprintf(f, "#include \"m68k.h\"\n"); + fprintf(f, "#include \"memory-uae.h\"\n"); #endif - fprintf (f, "#include \"readcpu.h\"\n"); - fprintf (f, "#include \"newcpu.h\"\n"); - fprintf (f, "#include \"comptbl.h\"\n"); - fprintf (f, "#include \"debug.h\"\n"); + fprintf(f, "#include \"readcpu.h\"\n"); + fprintf(f, "#include \"newcpu.h\"\n"); + fprintf(f, "#include \"comptbl.h\"\n"); + fprintf(f, "#include \"debug.h\"\n"); } static int postfix; -#ifdef UAE -static char *decodeEA (amodes mode, wordsizes size) +static char *decodeEA(amodes mode, wordsizes size) { static char buffer[80]; buffer[0] = 0; - switch (mode){ + switch (mode) { case Dreg: - strcpy (buffer,"Dn"); + strcpy(buffer, "Dn"); break; case Areg: - strcpy (buffer,"An"); + strcpy(buffer, "An"); break; case Aind: - strcpy (buffer,"(An)"); + strcpy(buffer, "(An)"); break; case Aipi: - strcpy (buffer,"(An)+"); + strcpy(buffer, "(An)+"); break; case Apdi: - strcpy (buffer,"-(An)"); + strcpy(buffer, "-(An)"); break; case Ad16: - strcpy (buffer,"(d16,An)"); + strcpy(buffer, "(d16,An)"); break; case Ad8r: - strcpy (buffer,"(d8,An,Xn)"); + strcpy(buffer, "(d8,An,Xn)"); break; case PC16: - strcpy (buffer,"(d16,PC)"); + strcpy(buffer, "(d16,PC)"); break; case PC8r: - strcpy (buffer,"(d8,PC,Xn)"); + strcpy(buffer, "(d8,PC,Xn)"); break; case absw: - strcpy (buffer,"(xxx).W"); + strcpy(buffer, "(xxx).W"); break; case absl: - strcpy (buffer,"(xxx).L"); + strcpy(buffer, "(xxx).L"); break; case imm: - switch (size){ + switch (size) { case sz_byte: - strcpy (buffer,"#.B"); + strcpy(buffer, "#.B"); break; case sz_word: - strcpy (buffer,"#.W"); + strcpy(buffer, "#.W"); break; case sz_long: - strcpy (buffer,"#.L"); + strcpy(buffer, "#.L"); break; default: break; } break; case imm0: - strcpy (buffer,"#.B"); + strcpy(buffer, "#.B"); break; case imm1: - strcpy (buffer,"#.W"); + strcpy(buffer, "#.W"); break; case imm2: - strcpy (buffer,"#.L"); + strcpy(buffer, "#.L"); break; case immi: - strcpy (buffer,"#"); + strcpy(buffer, "#"); break; default: @@ -3201,395 +3060,383 @@ static char *decodeEA (amodes mode, wordsizes size) return buffer; } -static char *outopcode (int opcode) +static char *outopcode(const char *name, int opcode) { static char out[100]; struct instr *ins; - int i; ins = &table68k[opcode]; - for (i = 0; lookuptab[i].name[0]; i++) { - if (ins->mnemo == lookuptab[i].mnemo) - break; - } - { - char *s = ua (lookuptab[i].name); - strcpy (out, s); - xfree (s); - } + strcpy(out, name); if (ins->smode == immi) - strcat (out, "Q"); + strcat(out, "Q"); if (ins->size == sz_byte) - strcat (out,".B"); + strcat(out, ".B"); if (ins->size == sz_word) - strcat (out,".W"); + strcat(out, ".W"); if (ins->size == sz_long) - strcat (out,".L"); - strcat (out," "); + strcat(out, ".L"); + strcat(out, " "); if (ins->suse) - strcat (out, decodeEA (ins->smode, ins->size)); + strcat(out, decodeEA(ins->smode, ins->size)); if (ins->duse) { - if (ins->suse) strcat (out,","); - strcat (out, decodeEA (ins->dmode, ins->size)); + if (ins->suse) strcat(out, ","); + strcat(out, decodeEA(ins->dmode, ins->size)); } return out; } -#endif static void -generate_one_opcode (int rp, int noflags) +generate_one_opcode(int rp, int noflags) { - int i; - uae_u16 smsk, dmsk; - unsigned int opcode = opcode_map[rp]; - int aborted=0; - int have_srcreg=0; - int have_dstreg=0; -#ifdef UAE - char *name; -#else + int i; + uae_u16 smsk, dmsk; + unsigned int opcode = opcode_map[rp]; + int aborted = 0; + int have_srcreg = 0; + int have_dstreg = 0; const char *name; -#endif + const char *tbl = noflags ? "nf" : "ff"; - if (table68k[opcode].mnemo == i_ILLG - || table68k[opcode].clev > cpu_level) - return; + if (table68k[opcode].mnemo == i_ILLG + || table68k[opcode].clev > cpu_level) + return; - for (i = 0; lookuptab[i].name[0]; i++) - { - if (table68k[opcode].mnemo == lookuptab[i].mnemo) - break; - } + for (i = 0; lookuptab[i].name[0]; i++) + { + if (table68k[opcode].mnemo == lookuptab[i].mnemo) + break; + } - if (table68k[opcode].handler != -1) - return; + if (table68k[opcode].handler != -1) + return; - switch (table68k[opcode].stype) - { - case 0: - smsk = 7; - break; - case 1: - smsk = 255; - break; - case 2: - smsk = 15; - break; - case 3: - smsk = 7; - break; - case 4: - smsk = 7; - break; - case 5: - smsk = 63; - break; + name = ua(lookuptab[i].name); + comprintf("/* %s */\n", outopcode(name, opcode)); + comprintf(RETTYPE " REGPARAM2 op_%x_%d_comp_%s(uae_u32 opcode) /* %s */\n{\n", opcode, postfix, tbl, name); + + switch (table68k[opcode].stype) + { + case 0: + smsk = 7; + break; + case 1: + smsk = 255; + break; + case 2: + smsk = 15; + break; + case 3: + smsk = 7; + break; + case 4: + smsk = 7; + break; + case 5: + smsk = 63; + break; #ifndef UAE - case 6: - smsk = 255; - break; + case 6: + smsk = 255; + break; #endif case 7: - smsk = 3; - break; - default: - assert(0); - } - dmsk = 7; - - next_cpu_level = -1; - if (table68k[opcode].suse - && table68k[opcode].smode != imm && table68k[opcode].smode != imm0 - && table68k[opcode].smode != imm1 && table68k[opcode].smode != imm2 - && table68k[opcode].smode != absw && table68k[opcode].smode != absl - && table68k[opcode].smode != PC8r && table68k[opcode].smode != PC16) - { - have_srcreg=1; - if (table68k[opcode].spos == -1) - { - if (((int) table68k[opcode].sreg) >= 128) - comprintf ("\tuae_s32 srcreg = (uae_s32)(uae_s8)%d;\n", (int) table68k[opcode].sreg); - else - comprintf ("\tuae_s32 srcreg = %d;\n", (int) table68k[opcode].sreg); + smsk = 3; + break; + default: + smsk = 0; + assert(0); } - else - { - char source[100]; - int pos = table68k[opcode].spos; + dmsk = 7; -#ifndef UAE - comprintf ("#if defined(HAVE_GET_WORD_UNSWAPPED) && !defined(FULLMMU)\n"); - - if (pos < 8 && (smsk >> (8 - pos)) != 0) - sprintf (source, "(((opcode >> %d) | (opcode << %d)) & %d)", - pos ^ 8, 8 - pos, dmsk); - else if (pos != 8) - sprintf (source, "((opcode >> %d) & %d)", pos ^ 8, smsk); - else - sprintf (source, "(opcode & %d)", smsk); - - if (table68k[opcode].stype == 3) - comprintf ("\tuae_u32 srcreg = imm8_table[%s];\n", source); - else if (table68k[opcode].stype == 1) - comprintf ("\tuae_u32 srcreg = (uae_s32)(uae_s8)%s;\n", source); - else - comprintf ("\tuae_u32 srcreg = %s;\n", source); - - comprintf ("#else\n"); -#endif - - if (pos) - sprintf (source, "((opcode >> %d) & %d)", pos, smsk); - else - sprintf (source, "(opcode & %d)", smsk); - - if (table68k[opcode].stype == 3) - comprintf ("\tuae_s32 srcreg = imm8_table[%s];\n", source); - else if (table68k[opcode].stype == 1) - comprintf ("\tuae_s32 srcreg = (uae_s32)(uae_s8)%s;\n", source); - else - comprintf ("\tuae_s32 srcreg = %s;\n", source); + next_cpu_level = -1; + if (table68k[opcode].suse + && table68k[opcode].smode != imm && table68k[opcode].smode != imm0 + && table68k[opcode].smode != imm1 && table68k[opcode].smode != imm2 + && table68k[opcode].smode != absw && table68k[opcode].smode != absl + && table68k[opcode].smode != PC8r && table68k[opcode].smode != PC16) + { + have_srcreg = 1; + if (table68k[opcode].spos == -1) + { + if (((int)table68k[opcode].sreg) >= 128) + comprintf("\tuae_s32 srcreg = (uae_s32)(uae_s8)%d;\n", (int)table68k[opcode].sreg); + else + comprintf("\tuae_s32 srcreg = %d;\n", (int)table68k[opcode].sreg); + } else + { + char source[100]; + int pos = table68k[opcode].spos; #ifndef UAE - comprintf ("#endif\n"); -#endif - } - } - if (table68k[opcode].duse - /* Yes, the dmode can be imm, in case of LINK or DBcc */ - && table68k[opcode].dmode != imm && table68k[opcode].dmode != imm0 - && table68k[opcode].dmode != imm1 && table68k[opcode].dmode != imm2 - && table68k[opcode].dmode != absw && table68k[opcode].dmode != absl) - { - have_dstreg=1; - if (table68k[opcode].dpos == -1) - { - if (((int) table68k[opcode].dreg) >= 128) - comprintf ("\tuae_s32 dstreg = (uae_s32)(uae_s8)%d;\n", (int) table68k[opcode].dreg); - else - comprintf ("\tuae_s32 dstreg = %d;\n", (int) table68k[opcode].dreg); + comprintf("#if defined(HAVE_GET_WORD_UNSWAPPED) && !defined(FULLMMU)\n"); +#else + comprintf("#if defined(HAVE_GET_WORD_UNSWAPPED)\n"); +#endif + + if (pos < 8 && (smsk >> (8 - pos)) != 0) + sprintf(source, "(((opcode >> %d) | (opcode << %d)) & %d)", + pos ^ 8, 8 - pos, dmsk); + else if (pos != 8) + sprintf(source, "((opcode >> %d) & %d)", pos ^ 8, smsk); + else + sprintf(source, "(opcode & %d)", smsk); + + if (table68k[opcode].stype == 3) + comprintf("\tuae_u32 srcreg = imm8_table[%s];\n", source); + else if (table68k[opcode].stype == 1) + comprintf("\tuae_u32 srcreg = (uae_s32)(uae_s8)%s;\n", source); + else + comprintf("\tuae_u32 srcreg = %s;\n", source); + + comprintf("#else\n"); + + if (pos) + sprintf(source, "((opcode >> %d) & %d)", pos, smsk); + else + sprintf(source, "(opcode & %d)", smsk); + + if (table68k[opcode].stype == 3) + comprintf("\tuae_s32 srcreg = imm8_table[%s];\n", source); + else if (table68k[opcode].stype == 1) + comprintf("\tuae_s32 srcreg = (uae_s32)(uae_s8)%s;\n", source); + else + comprintf("\tuae_s32 srcreg = %s;\n", source); + + comprintf("#endif\n"); + } } - else + if (table68k[opcode].duse + /* Yes, the dmode can be imm, in case of LINK or DBcc */ + && table68k[opcode].dmode != imm && table68k[opcode].dmode != imm0 + && table68k[opcode].dmode != imm1 && table68k[opcode].dmode != imm2 + && table68k[opcode].dmode != absw && table68k[opcode].dmode != absl) { - int pos = table68k[opcode].dpos; + have_dstreg = 1; + if (table68k[opcode].dpos == -1) + { + if (((int)table68k[opcode].dreg) >= 128) + comprintf("\tuae_s32 dstreg = (uae_s32)(uae_s8)%d;\n", (int)table68k[opcode].dreg); + else + comprintf("\tuae_s32 dstreg = %d;\n", (int)table68k[opcode].dreg); + } else + { + int pos = table68k[opcode].dpos; #ifndef UAE - comprintf ("#if defined(HAVE_GET_WORD_UNSWAPPED) && !defined(FULLMMU)\n"); - - if (pos < 8 && (dmsk >> (8 - pos)) != 0) - comprintf ("\tuae_u32 dstreg = ((opcode >> %d) | (opcode << %d)) & %d;\n", - pos ^ 8, 8 - pos, dmsk); - else if (pos != 8) - comprintf ("\tuae_u32 dstreg = (opcode >> %d) & %d;\n", - pos ^ 8, dmsk); - else - comprintf ("\tuae_u32 dstreg = opcode & %d;\n", dmsk); - - comprintf ("#else\n"); -#endif - - if (pos) - comprintf ("\tuae_u32 dstreg = (opcode >> %d) & %d;\n", - pos, dmsk); - else - comprintf ("\tuae_u32 dstreg = opcode & %d;\n", dmsk); + comprintf("#if defined(HAVE_GET_WORD_UNSWAPPED) && !defined(FULLMMU)\n"); -#ifndef UAE - comprintf ("#endif\n"); -#endif - } - } - - if (have_srcreg && have_dstreg && - (table68k[opcode].dmode==Areg || - table68k[opcode].dmode==Aind || - table68k[opcode].dmode==Aipi || - table68k[opcode].dmode==Apdi || - table68k[opcode].dmode==Ad16 || - table68k[opcode].dmode==Ad8r) && - (table68k[opcode].smode==Areg || - table68k[opcode].smode==Aind || - table68k[opcode].smode==Aipi || - table68k[opcode].smode==Apdi || - table68k[opcode].smode==Ad16 || - table68k[opcode].smode==Ad8r) - ) { - comprintf("\tuae_u32 dodgy=(srcreg==(uae_s32)dstreg);\n"); - } - else { - comprintf("\tuae_u32 dodgy=0;\n"); - } - comprintf("\tuae_u32 m68k_pc_offset_thisinst=m68k_pc_offset;\n"); - comprintf("\tm68k_pc_offset+=2;\n"); - - aborted=gen_opcode (opcode); - { - char flags[64 * 6]; - *flags = '\0'; - if (global_isjump) strcat(flags, "COMP_OPCODE_ISJUMP|"); - if (long_opcode) strcat(flags, "COMP_OPCODE_LONG_OPCODE|"); - if (global_cmov) strcat(flags, "COMP_OPCODE_CMOV|"); - if (global_isaddx) strcat(flags, "COMP_OPCODE_ISADDX|"); - if (global_iscjump) strcat(flags, "COMP_OPCODE_ISCJUMP|"); - if (global_fpu) strcat(flags, "COMP_OPCODE_USES_FPU|"); - if (*flags) - flags[strlen(flags) - 1] = '\0'; - else - strcpy(flags, "0"); + if (pos < 8 && (dmsk >> (8 - pos)) != 0) + comprintf("\tuae_u32 dstreg = ((opcode >> %d) | (opcode << %d)) & %d;\n", + pos ^ 8, 8 - pos, dmsk); + else if (pos != 8) + comprintf("\tuae_u32 dstreg = (opcode >> %d) & %d;\n", + pos ^ 8, dmsk); + else + comprintf("\tuae_u32 dstreg = opcode & %d;\n", dmsk); -#ifdef UAE - comprintf ("return 0;\n"); + comprintf("#else\n"); #endif - comprintf ("}\n"); -#ifdef UAE - name = ua (lookuptab[i].name); -#else - name = lookuptab[i].name; + if (pos) + comprintf("\tuae_u32 dstreg = (opcode >> %d) & %d;\n", + pos, dmsk); + else + comprintf("\tuae_u32 dstreg = opcode & %d;\n", dmsk); + +#ifndef UAE + comprintf("#endif\n"); #endif - if (aborted) { - fprintf (stblfile, "{ NULL, %u, %s }, /* %s */\n", opcode, flags, name); - com_discard(); + } + } + + if (have_srcreg && have_dstreg && + (table68k[opcode].dmode == Areg || + table68k[opcode].dmode == Aind || + table68k[opcode].dmode == Aipi || + table68k[opcode].dmode == Apdi || + table68k[opcode].dmode == Ad16 || + table68k[opcode].dmode == Ad8r) && + (table68k[opcode].smode == Areg || + table68k[opcode].smode == Aind || + table68k[opcode].smode == Aipi || + table68k[opcode].smode == Apdi || + table68k[opcode].smode == Ad16 || + table68k[opcode].smode == Ad8r) + ) { + comprintf("\tuae_u32 dodgy=(srcreg==(uae_s32)dstreg);\n"); } else { - const char *tbl = noflags ? "nf" : "ff"; -#ifdef UAE - printf ("/* %s */\n", outopcode (opcode)); -#else - printf ("/* %s */\n", name); -#endif - fprintf (stblfile, "{ op_%x_%d_comp_%s, %u, %s }, /* %s */\n", opcode, postfix, tbl, opcode, flags, name); - fprintf (headerfile, "extern compop_func op_%x_%d_comp_%s;\n", opcode, postfix, tbl); - printf (RETTYPE " REGPARAM2 op_%x_%d_comp_%s(uae_u32 opcode)\n{\n", opcode, postfix, tbl); - com_flush(); + comprintf("\tuae_u32 dodgy=0;\n"); } -#ifdef UAE - xfree (name); -#endif - } - opcode_next_clev[rp] = next_cpu_level; - opcode_last_postfix[rp] = postfix; + comprintf("\tuae_u32 m68k_pc_offset_thisinst=m68k_pc_offset;\n"); + comprintf("\tm68k_pc_offset+=2;\n"); + + aborted = gen_opcode(opcode); + { + char flags[64 * 6]; + *flags = '\0'; + if (global_isjump) strcat(flags, "COMP_OPCODE_ISJUMP|"); + if (long_opcode) strcat(flags, "COMP_OPCODE_LONG_OPCODE|"); + if (global_cmov) strcat(flags, "COMP_OPCODE_CMOV|"); + if (global_isaddx) strcat(flags, "COMP_OPCODE_ISADDX|"); + if (global_iscjump) strcat(flags, "COMP_OPCODE_ISCJUMP|"); + if (global_fpu) strcat(flags, "COMP_OPCODE_USES_FPU|"); + if (*flags) + flags[strlen(flags) - 1] = '\0'; + else + strcpy(flags, "0"); + +#ifdef UAE /* RETTYPE != void */ + comprintf("return 0;\n"); +#endif + comprintf("}\n"); + + if (aborted) { + fprintf(stblfile, "{ NULL, %u, %s }, /* %s */\n", opcode, flags, name); + com_discard(); + } else { + fprintf(stblfile, "{ op_%x_%d_comp_%s, %u, %s }, /* %s */\n", opcode, postfix, tbl, opcode, flags, name); + fprintf(headerfile, "extern compop_func op_%x_%d_comp_%s;\n", opcode, postfix, tbl); + com_flush(); + } + } + opcode_next_clev[rp] = next_cpu_level; + opcode_last_postfix[rp] = postfix; } static void -generate_func (int noflags) +generate_func(int noflags) { - int i, j, rp; + int i, j, rp; const char *tbl = noflags ? "nf" : "ff"; - using_prefetch = 0; - using_exception_3 = 0; - for (i = 0; i < 1; i++) /* We only do one level! */ - { - cpu_level = NEXT_CPU_LEVEL - i; - postfix = i; - - fprintf (stblfile, "const struct comptbl op_smalltbl_%d_comp_%s[] = {\n", postfix, tbl); - - /* sam: this is for people with low memory (eg. me :)) */ - printf ("\n" - "#if !defined(PART_1) && !defined(PART_2) && " - "!defined(PART_3) && !defined(PART_4) && " - "!defined(PART_5) && !defined(PART_6) && " - "!defined(PART_7) && !defined(PART_8)" - "\n" - "#define PART_1 1\n" - "#define PART_2 1\n" - "#define PART_3 1\n" - "#define PART_4 1\n" - "#define PART_5 1\n" - "#define PART_6 1\n" - "#define PART_7 1\n" - "#define PART_8 1\n" - "#endif\n\n"); + using_prefetch = 0; + using_exception_3 = 0; + for (i = 0; i < 1; i++) /* We only do one level! */ + { + cpu_level = NEXT_CPU_LEVEL - i; + postfix = i; + + fprintf(stblfile, "const struct comptbl op_smalltbl_%d_comp_%s[] = {\n", postfix, tbl); + + /* sam: this is for people with low memory (eg. me :)) */ + printf("\n" + "#if !defined(PART_1) && !defined(PART_2) && " + "!defined(PART_3) && !defined(PART_4) && " + "!defined(PART_5) && !defined(PART_6) && " + "!defined(PART_7) && !defined(PART_8)" + "\n" + "#define PART_1 1\n" + "#define PART_2 1\n" + "#define PART_3 1\n" + "#define PART_4 1\n" + "#define PART_5 1\n" + "#define PART_6 1\n" + "#define PART_7 1\n" + "#define PART_8 1\n" + "#endif\n\n"); #ifdef UAE - printf ("extern void comp_fpp_opp();\n" - "extern void comp_fscc_opp();\n" - "extern void comp_fbcc_opp();\n\n"); + + printf("#ifdef USE_JIT_FPU\n"); + printf("extern void comp_fpp_opp();\n" + "extern void comp_fscc_opp();\n" + "extern void comp_fbcc_opp();\n"); + printf("#endif\n"); + printf("\n"); #endif - rp = 0; - for (j = 1; j <= 8; ++j) - { - int k = (j * nr_cpuop_funcs) / 8; - printf ("#ifdef PART_%d\n", j); - for (; rp < k; rp++) - generate_one_opcode (rp,noflags); - printf ("#endif\n\n"); + rp = 0; + for (j = 1; j <= 8; ++j) + { + int k = (j * nr_cpuop_funcs) / 8; + printf("#ifdef PART_%d\n", j); + for (; rp < k; rp++) + generate_one_opcode(rp, noflags); + printf("#endif\n\n"); + } + + fprintf(stblfile, "{ 0, 65536, 0 }};\n"); } - fprintf (stblfile, "{ 0, 65536, 0 }};\n"); - } +} +#if (defined(OS_cygwin) || defined(OS_mingw)) && defined(EXTENDED_SIGSEGV) +void cygwin_mingw_abort() +{ +#undef abort + abort(); } +#endif -#ifdef __cplusplus -int main(int, char **) +#if defined(FSUAE) && defined (WINDOWS) +#include "windows.h" +int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) #else -int main() +int main(void) #endif { - read_table68k (); - do_merges (); + init_table68k(); - opcode_map = (int *) malloc (sizeof (int) * nr_cpuop_funcs); - opcode_last_postfix = (int *) malloc (sizeof (int) * nr_cpuop_funcs); - opcode_next_clev = (int *) malloc (sizeof (int) * nr_cpuop_funcs); - counts = (unsigned long *) malloc (65536 * sizeof (unsigned long)); - read_counts (); + opcode_map = (int *)malloc(sizeof(int) * nr_cpuop_funcs); + opcode_last_postfix = (int *)malloc(sizeof(int) * nr_cpuop_funcs); + opcode_next_clev = (int *)malloc(sizeof(int) * nr_cpuop_funcs); + counts = (unsigned long *)malloc(65536 * sizeof(unsigned long)); + read_counts(); - /* It would be a lot nicer to put all in one file (we'd also get rid of - * cputbl.h that way), but cpuopti can't cope. That could be fixed, but - * I don't dare to touch the 68k version. */ + /* It would be a lot nicer to put all in one file (we'd also get rid of + * cputbl.h that way), but cpuopti can't cope. That could be fixed, but + * I don't dare to touch the 68k version. */ - headerfile = fopen (GEN_PATH "comptbl.h", "wb"); - fprintf (headerfile, "" + headerfile = fopen(GEN_PATH "comptbl.h", "wb"); + fprintf(headerfile, "" "extern const struct comptbl op_smalltbl_0_comp_nf[];\n" "extern const struct comptbl op_smalltbl_0_comp_ff[];\n" ""); - stblfile = fopen (GEN_PATH "compstbl.cpp", "wb"); - if (freopen (GEN_PATH "compemu.cpp", "wb", stdout) == NULL) { + stblfile = fopen(GEN_PATH "compstbl.cpp", "wb"); + if (freopen(GEN_PATH "compemu.cpp", "wb", stdout) == NULL) { abort(); } - generate_includes (stdout); - generate_includes (stblfile); + generate_includes(stdout); + generate_includes(stblfile); - printf("#include \"" JIT_PATH "compemu.h\"\n"); + printf("#include \"" JIT_PATH "compemu.h\"\n"); + printf("#include \"" JIT_PATH "flags_x86.h\"\n"); - noflags=0; - generate_func (noflags); + noflags = 0; + generate_func(noflags); free(opcode_map); free(opcode_last_postfix); free(opcode_next_clev); free(counts); - opcode_map = (int *) malloc (sizeof (int) * nr_cpuop_funcs); - opcode_last_postfix = (int *) malloc (sizeof (int) * nr_cpuop_funcs); - opcode_next_clev = (int *) malloc (sizeof (int) * nr_cpuop_funcs); - counts = (unsigned long *) malloc (65536 * sizeof (unsigned long)); - read_counts (); - noflags=1; - generate_func (noflags); + opcode_map = (int *)malloc(sizeof(int) * nr_cpuop_funcs); + opcode_last_postfix = (int *)malloc(sizeof(int) * nr_cpuop_funcs); + opcode_next_clev = (int *)malloc(sizeof(int) * nr_cpuop_funcs); + counts = (unsigned long *)malloc(65536 * sizeof(unsigned long)); + read_counts(); + noflags = 1; + generate_func(noflags); - printf ("#endif\n"); - fprintf (stblfile, "#endif\n"); + printf("#endif\n"); + fprintf(stblfile, "#endif\n"); free(opcode_map); free(opcode_last_postfix); free(opcode_next_clev); free(counts); - free (table68k); - fclose (stblfile); - fclose (headerfile); - return 0; + free(table68k); + fclose(stblfile); + fclose(headerfile); + (void)disasm_this_inst; + return 0; } #ifdef UAE -void write_log (const TCHAR *format,...) +void write_log(const TCHAR *format, ...) { } #endif diff --git a/jit/memory-uae.h b/jit/memory-uae.h new file mode 100644 index 00000000..d211c7b4 --- /dev/null +++ b/jit/memory-uae.h @@ -0,0 +1,2 @@ +#include "options.h" +#include "memory.h" diff --git a/main.cpp b/main.cpp index 55971c5f..50630541 100644 --- a/main.cpp +++ b/main.cpp @@ -1135,6 +1135,7 @@ static int real_main2 (int argc, TCHAR **argv) logging_init (); /* Yes, we call this twice - the first case handles when the user has loaded a config using the cmd-line. This case handles loads through the GUI. */ + compiler_init(); #ifdef NATMEM_OFFSET if (!init_shm ()) { if (currprefs.start_gui) diff --git a/memory.cpp b/memory.cpp index 0a15b8d1..5c710be1 100644 --- a/memory.cpp +++ b/memory.cpp @@ -3092,7 +3092,7 @@ static void map_banks2 (addrbank *bank, int start, int size, int realsize, int q if (quick <= 0) old = debug_bankchange (-1); - flush_icache_hard (3); /* Sure don't want to keep any old mappings around! */ + flush_icache(3); /* Sure don't want to keep any old mappings around! */ #ifdef NATMEM_OFFSET if (!quick) delete_shmmaps (start << 16, size << 16); diff --git a/newcpu.cpp b/newcpu.cpp index 20e26e4a..32adbe34 100644 --- a/newcpu.cpp +++ b/newcpu.cpp @@ -93,6 +93,7 @@ int m68k_pc_indirect; bool m68k_interrupt_delay; static bool m68k_reset_delay; static bool ismoves_nommu; +static bool need_opcode_swap; static volatile uae_atomic uae_interrupt; static volatile uae_atomic uae_interrupts2[IRQ_SOURCE_MAX]; @@ -150,6 +151,8 @@ static int fallback_new_cpu_model; int cpu_last_stop_vpos, cpu_stopped_lines; +void (*flush_icache)(int); + #if COUNT_INSTRS static unsigned long int instrcount[65536]; static uae_u16 opcodenums[65536]; @@ -1764,17 +1767,26 @@ STATIC_INLINE void count_instr (unsigned int opcode) { } +static uae_u32 opcode_swap(uae_u16 opcode) +{ + if (!need_opcode_swap) + return opcode; + return do_byteswap_16(opcode); +} + uae_u32 REGPARAM2 op_illg_1 (uae_u32 opcode) { - op_illg (opcode); + opcode = opcode_swap(opcode); + op_illg(opcode); return 4; } uae_u32 REGPARAM2 op_unimpl_1 (uae_u32 opcode) { + opcode = opcode_swap(opcode); if ((opcode & 0xf000) == 0xf000 || currprefs.cpu_model < 68060) - op_illg (opcode); + op_illg(opcode); else - op_unimpl (opcode); + op_unimpl(opcode); return 4; } @@ -1782,26 +1794,41 @@ uae_u32 REGPARAM2 op_unimpl_1 (uae_u32 opcode) static const struct cputbl *cputbls[6][8] = { // 68000 - { op_smalltbl_5_ff, op_smalltbl_45_ff, op_smalltbl_55_ff, op_smalltbl_12_ff, op_smalltbl_14_ff, NULL, NULL, NULL }, + { op_smalltbl_5, op_smalltbl_45, op_smalltbl_55, op_smalltbl_12, op_smalltbl_14, NULL, NULL, NULL }, // 68010 - { op_smalltbl_4_ff, op_smalltbl_44_ff, op_smalltbl_54_ff, op_smalltbl_11_ff, op_smalltbl_13_ff, NULL, NULL, NULL }, + { op_smalltbl_4, op_smalltbl_44, op_smalltbl_54, op_smalltbl_11, op_smalltbl_13, NULL, NULL, NULL }, // 68020 - { op_smalltbl_3_ff, op_smalltbl_43_ff, op_smalltbl_53_ff, op_smalltbl_20_ff, op_smalltbl_21_ff, NULL, NULL, NULL }, + { op_smalltbl_3, op_smalltbl_43, op_smalltbl_53, op_smalltbl_20, op_smalltbl_21, NULL, NULL, NULL }, // 68030 - { op_smalltbl_2_ff, op_smalltbl_42_ff, op_smalltbl_52_ff, op_smalltbl_22_ff, op_smalltbl_23_ff, op_smalltbl_32_ff, op_smalltbl_34_ff, op_smalltbl_35_ff }, + { op_smalltbl_2, op_smalltbl_42, op_smalltbl_52, op_smalltbl_22, op_smalltbl_23, op_smalltbl_32, op_smalltbl_34, op_smalltbl_35 }, // 68040 - { op_smalltbl_1_ff, op_smalltbl_41_ff, op_smalltbl_51_ff, op_smalltbl_25_ff, op_smalltbl_25_ff, op_smalltbl_31_ff, op_smalltbl_31_ff, op_smalltbl_31_ff }, + { op_smalltbl_1, op_smalltbl_41, op_smalltbl_51, op_smalltbl_25, op_smalltbl_25, op_smalltbl_31, op_smalltbl_31, op_smalltbl_31 }, // 68060 - { op_smalltbl_0_ff, op_smalltbl_40_ff, op_smalltbl_50_ff, op_smalltbl_24_ff, op_smalltbl_24_ff, op_smalltbl_33_ff, op_smalltbl_33_ff, op_smalltbl_33_ff } + { op_smalltbl_0, op_smalltbl_40, op_smalltbl_50, op_smalltbl_24, op_smalltbl_24, op_smalltbl_33, op_smalltbl_33, op_smalltbl_33 } }; +const struct cputbl *uaegetjitcputbl(void) +{ + int lvl = (currprefs.cpu_model - 68000) / 10; + if (lvl > 4) + lvl--; + int index = currprefs.comptrustbyte ? 0 : 1; + return cputbls[lvl][index]; +} + +const struct cputbl *getjitcputbl(int cpulvl, int direct) +{ + return cputbls[cpulvl][1 + direct]; +} + static void build_cpufunctbl (void) { int i, opcnt; unsigned long opcode; const struct cputbl *tbl = NULL; - int lvl, mode; + int lvl, mode, jit; + jit = 0; if (!currprefs.cachesize) { if (currprefs.mmu_model) { if (currprefs.cpu_cycle_exact) @@ -1821,6 +1848,7 @@ static void build_cpufunctbl (void) } else { mode = 1; m68k_pc_indirect = 0; + jit = 1; if (currprefs.comptrustbyte) { mode = 2; m68k_pc_indirect = -1; @@ -1838,9 +1866,9 @@ static void build_cpufunctbl (void) for (opcode = 0; opcode < 65536; opcode++) cpufunctbl[opcode] = op_illg_1; - for (i = 0; tbl[i].handler != NULL; i++) { + for (i = 0; tbl[i].handler_ff != NULL; i++) { opcode = tbl[i].opcode; - cpufunctbl[opcode] = tbl[i].handler; + cpufunctbl[opcode] = tbl[i].handler_ff; cpudatatbl[opcode].length = tbl[i].length; cpudatatbl[opcode].disp020[0] = tbl[i].disp020[0]; cpudatatbl[opcode].disp020[1] = tbl[i].disp020[1]; @@ -1849,10 +1877,10 @@ static void build_cpufunctbl (void) /* hack fpu to 68000/68010 mode */ if (currprefs.fpu_model && currprefs.cpu_model < 68020) { - tbl = op_smalltbl_3_ff; - for (i = 0; tbl[i].handler != NULL; i++) { + tbl = op_smalltbl_3; + for (i = 0; tbl[i].handler_ff != NULL; i++) { if ((tbl[i].opcode & 0xfe00) == 0xf200) { - cpufunctbl[tbl[i].opcode] = tbl[i].handler; + cpufunctbl[tbl[i].opcode] = tbl[i].handler_ff; cpudatatbl[tbl[i].opcode].length = tbl[i].length; cpudatatbl[tbl[i].opcode].disp020[0] = tbl[i].disp020[0]; cpudatatbl[tbl[i].opcode].disp020[1] = tbl[i].disp020[1]; @@ -1916,6 +1944,21 @@ static void build_cpufunctbl (void) } } + + need_opcode_swap = 0; +#ifdef HAVE_GET_WORD_UNSWAPPED + if (jit) { + cpuop_func **tmp = xmalloc(cpuop_func*, 65536); + memcpy(tmp, cpufunctbl, sizeof(cpuop_func*) * 65536); + for (int i = 0; i < 65536; i++) { + int offset = do_byteswap_16(i); + cpufunctbl[offset] = tmp[i]; + } + xfree(tmp); + need_opcode_swap = 1; + } +#endif + write_log (_T("Building CPU, %d opcodes (%d %d %d)\n"), opcnt, lvl, currprefs.cpu_cycle_exact ? -2 : currprefs.cpu_memory_cycle_exact ? -1 : currprefs.cpu_compatible ? 1 : 0, currprefs.address_space_24); @@ -1939,7 +1982,7 @@ static void build_cpufunctbl (void) } m68k_interrupt_delay = false; if (currprefs.cpu_cycle_exact) { - if (tbl == op_smalltbl_14_ff || tbl == op_smalltbl_13_ff || tbl == op_smalltbl_21_ff || tbl == op_smalltbl_23_ff) + if (tbl == op_smalltbl_14 || tbl == op_smalltbl_13 || tbl == op_smalltbl_21 || tbl == op_smalltbl_23) m68k_interrupt_delay = true; } else if (currprefs.cpu_compatible) { if (currprefs.cpu_model <= 68010 && currprefs.m68k_speed == 0) { @@ -2174,8 +2217,7 @@ void init_m68k (void) } #endif - read_table68k (); - do_merges (); + init_table68k(); write_log (_T("%d CPU functions\n"), nr_cpuop_funcs); } @@ -3242,7 +3284,7 @@ kludge_me_do: } // address = format $2 stack frame address field -static void ExceptionX (int nr, uaecptr address) +static void ExceptionX (int nr, uaecptr address, uaecptr oldpc) { uaecptr pc = m68k_getpc(); regs.exception = nr; @@ -3253,12 +3295,9 @@ static void ExceptionX (int nr, uaecptr address) if (!regs.s) { regs.instruction_pc_user_exception = pc; } - -#ifdef JIT - if (currprefs.cachesize) - regs.instruction_pc = address == -1 ? pc : address; -#endif - + if (oldpc != 0xffffffff) { + regs.instruction_pc = oldpc; + } if (debug_illegal && !in_rom(pc)) { if (nr <= 63 && (debug_illegal_mask & ((uae_u64)1 << nr))) { write_log(_T("Exception %d breakpoint\n"), nr); @@ -3291,10 +3330,10 @@ static void ExceptionX (int nr, uaecptr address) } } -void REGPARAM2 Exception_cpu(int nr) +void REGPARAM2 Exception_cpu_oldpc(int nr, uaecptr oldpc) { bool t0 = currprefs.cpu_model >= 68020 && regs.t0 && !regs.t1; - ExceptionX (nr, -1); + ExceptionX(nr, 0xffffffff, oldpc); // Check T0 trace // RTE format error ignores T0 trace if (nr != 14) { @@ -3306,13 +3345,17 @@ void REGPARAM2 Exception_cpu(int nr) } } } -void REGPARAM2 Exception (int nr) +void REGPARAM2 Exception_cpu(int nr) +{ + Exception_cpu_oldpc(nr, 0xffffffff); +} +void REGPARAM2 Exception(int nr) { - ExceptionX (nr, -1); + ExceptionX(nr, 0xffffffff, 0xffffffff); } -void REGPARAM2 ExceptionL (int nr, uaecptr address) +void REGPARAM2 ExceptionL(int nr, uaecptr address) { - ExceptionX (nr, address); + ExceptionX(nr, address, 0xffffffff); } static void bus_error(void) @@ -3600,10 +3643,12 @@ uae_u32 REGPARAM2 op_illg (uae_u32 opcode) int inrom = in_rom (pc); int inrt = in_rtarea (pc); - if ((opcode == 0x4afc || opcode == 0xfc4a) && !valid_address(pc, 4) && valid_address(pc - 4, 4)) { - // PC fell off the end of RAM - bus_error(); - return 4; + if (opcode == 0x4afc || opcode == 0xfc4a) { + if (!valid_address(pc, 4) && valid_address(pc - 4, 4)) { + // PC fell off the end of RAM + bus_error(); + return 4; + } } // BKPT? @@ -5139,19 +5184,35 @@ void do_nothing (void) } } +static uae_u32 get_jit_opcode(void) +{ + uae_u32 opcode; + if (currprefs.cpu_compatible) { + opcode = get_word_020_prefetchf(m68k_getpc()); +#ifdef HAVE_GET_WORD_UNSWAPPED + opcode = do_byteswap_16(opcode); +#endif + } else { +#ifdef HAVE_GET_WORD_UNSWAPPED + opcode = do_get_mem_word_unswapped((uae_u16 *)get_real_address(m68k_getpc())); +#else + opcode = x_get_iword(0); +#endif + } + return opcode; +} + void exec_nostats (void) { struct regstruct *r = ®s; for (;;) { - if (currprefs.cpu_compatible) { - r->opcode = get_word_020_prefetchf(m68k_getpc()); - } else { - r->opcode = x_get_iword(0); - } - cpu_cycles = (*cpufunctbl[r->opcode])(r->opcode) >> 16; - cpu_cycles = adjust_cycles (cpu_cycles); + r->opcode = get_jit_opcode(); + + (*cpufunctbl[r->opcode])(r->opcode); + + cpu_cycles = 4 * CYCLE_UNIT; // adjust_cycles(cpu_cycles); if (!currprefs.cpu_thread) { do_cycles (cpu_cycles); @@ -5167,7 +5228,7 @@ void exec_nostats (void) } } -void execute_normal (void) +void execute_normal(void) { struct regstruct *r = ®s; int blocklen; @@ -5183,22 +5244,21 @@ void execute_normal (void) start_pc = r->pc; for (;;) { /* Take note: This is the do-it-normal loop */ - regs.instruction_pc = m68k_getpc (); - if (currprefs.cpu_compatible) { - r->opcode = get_word_020_prefetchf (regs.instruction_pc); - } else { - r->opcode = x_get_iword(0); - } + r->opcode = get_jit_opcode(); special_mem = DISTRUST_CONSISTENT_MEM; pc_hist[blocklen].location = (uae_u16*)r->pc_p; - cpu_cycles = (*cpufunctbl[r->opcode])(r->opcode) >> 16; - cpu_cycles = adjust_cycles(cpu_cycles); + (*cpufunctbl[r->opcode])(r->opcode); + + cpu_cycles = 4 * CYCLE_UNIT; + +// cpu_cycles = adjust_cycles(cpu_cycles); if (!currprefs.cpu_thread) { do_cycles (cpu_cycles); } total_cycles += cpu_cycles; + pc_hist[blocklen].specmem = special_mem; blocklen++; if (end_block (r->opcode) || blocklen >= MAXRUN || r->spcflags || uae_int_requested) { @@ -8146,7 +8206,6 @@ static bool maybe_icache030(uae_u32 addr) { int lws; uae_u32 tag; - uae_u32 data; struct cache030 *c; regs.fc030 = (regs.s ? 4 : 0) | 2; diff --git a/newcpu_common.cpp b/newcpu_common.cpp index 25b268ea..7427add8 100644 --- a/newcpu_common.cpp +++ b/newcpu_common.cpp @@ -1212,7 +1212,7 @@ static void divul_overflow(uae_u16 extra, uae_s64 a) } } -static void divsl_divbyzero(uae_u16 extra, uae_s64 a) +static void divsl_divbyzero(uae_u16 extra, uae_s64 a, uaecptr oldpc) { if (currprefs.cpu_model >= 68040) { SET_CFLG(0); @@ -1221,10 +1221,10 @@ static void divsl_divbyzero(uae_u16 extra, uae_s64 a) SET_ZFLG(1); SET_CFLG(0); } - Exception_cpu(5); + Exception_cpu_oldpc(5, oldpc); } -static void divul_divbyzero(uae_u16 extra, uae_s64 a) +static void divul_divbyzero(uae_u16 extra, uae_s64 a, uaecptr oldpc) { if (currprefs.cpu_model >= 68040) { SET_CFLG(0); @@ -1236,10 +1236,10 @@ static void divul_divbyzero(uae_u16 extra, uae_s64 a) SET_VFLG(1); SET_CFLG(0); } - Exception_cpu(5); + Exception_cpu_oldpc(5, oldpc); } -int m68k_divl(uae_u32 opcode, uae_u32 src, uae_u16 extra) +int m68k_divl(uae_u32 opcode, uae_u32 src, uae_u16 extra, uaecptr oldpc) { if ((extra & 0x400) && currprefs.int_no_unimplemented && currprefs.cpu_model == 68060) { op_unimpl (opcode); @@ -1257,7 +1257,7 @@ int m68k_divl(uae_u32 opcode, uae_u32 src, uae_u16 extra) } if (src == 0) { - divsl_divbyzero(extra, a); + divsl_divbyzero(extra, a, oldpc); return 0; } @@ -1291,7 +1291,7 @@ int m68k_divl(uae_u32 opcode, uae_u32 src, uae_u16 extra) } if (src == 0) { - divul_divbyzero(extra, a); + divul_divbyzero(extra, a, oldpc); return 0; } diff --git a/od-win32/machdep/m68k.cpp b/od-win32/machdep/m68k.cpp index b8198b63..5094e027 100644 --- a/od-win32/machdep/m68k.cpp +++ b/od-win32/machdep/m68k.cpp @@ -6,32 +6,81 @@ /* * Test CCR condition */ -int cctrue (int cc) + +#ifndef SAHF_SETO_PROFITABLE + +int cctrue(int cc) { uae_u32 cznv = regflags.cznv; switch (cc) { - case 0: return 1; /* T */ - case 1: return 0; /* F */ - case 2: return (cznv & (FLAGVAL_C | FLAGVAL_Z)) == 0; /* !CFLG && !ZFLG HI */ - case 3: return (cznv & (FLAGVAL_C | FLAGVAL_Z)) != 0; /* CFLG || ZFLG LS */ - case 4: return (cznv & FLAGVAL_C) == 0; /* !CFLG CC */ - case 5: return (cznv & FLAGVAL_C) != 0; /* CFLG CS */ - case 6: return (cznv & FLAGVAL_Z) == 0; /* !ZFLG NE */ - case 7: return (cznv & FLAGVAL_Z) != 0; /* ZFLG EQ */ - case 8: return (cznv & FLAGVAL_V) == 0; /* !VFLG VC */ - case 9: return (cznv & FLAGVAL_V) != 0; /* VFLG VS */ - case 10: return (cznv & FLAGVAL_N) == 0; /* !NFLG PL */ - case 11: return (cznv & FLAGVAL_N) != 0; /* NFLG MI */ - - case 12: /* NFLG == VFLG GE */ - return ((cznv >> FLAGBIT_N) & 1) == ((cznv >> FLAGBIT_V) & 1); - case 13: /* NFLG != VFLG LT */ - return ((cznv >> FLAGBIT_N) & 1) != ((cznv >> FLAGBIT_V) & 1); - case 14: /* !GET_ZFLG && (GET_NFLG == GET_VFLG); GT */ - return !(cznv & FLAGVAL_Z) && (((cznv >> FLAGBIT_N) & 1) == ((cznv >> FLAGBIT_V) & 1)); - case 15: /* GET_ZFLG || (GET_NFLG != GET_VFLG); LE */ - return (cznv & FLAGVAL_Z) || (((cznv >> FLAGBIT_N) & 1) != ((cznv >> FLAGBIT_V) & 1)); - } + case 0: return 1; /* T */ + case 1: return 0; /* F */ + case 2: return (cznv & (FLAGVAL_C | FLAGVAL_Z)) == 0; /* !CFLG && !ZFLG HI */ + case 3: return (cznv & (FLAGVAL_C | FLAGVAL_Z)) != 0; /* CFLG || ZFLG LS */ + case 4: return (cznv & FLAGVAL_C) == 0; /* !CFLG CC */ + case 5: return (cznv & FLAGVAL_C) != 0; /* CFLG CS */ + case 6: return (cznv & FLAGVAL_Z) == 0; /* !ZFLG NE */ + case 7: return (cznv & FLAGVAL_Z) != 0; /* ZFLG EQ */ + case 8: return (cznv & FLAGVAL_V) == 0; /* !VFLG VC */ + case 9: return (cznv & FLAGVAL_V) != 0; /* VFLG VS */ + case 10: return (cznv & FLAGVAL_N) == 0; /* !NFLG PL */ + case 11: return (cznv & FLAGVAL_N) != 0; /* NFLG MI */ +#if FLAGBIT_N > FLAGBIT_V + case 12: return (((cznv << (FLAGBIT_N - FLAGBIT_V)) ^ cznv) & FLAGVAL_N) == 0; /* NFLG == VFLG GE */ + case 13: return (((cznv << (FLAGBIT_N - FLAGBIT_V)) ^ cznv) & FLAGVAL_N) != 0; /* NFLG != VFLG LT */ + case 14: cznv &= (FLAGVAL_N | FLAGVAL_Z | FLAGVAL_V); /* !ZFLG && (NFLG == VFLG) GT */ + return (((cznv << (FLAGBIT_N - FLAGBIT_V)) ^ cznv) & (FLAGVAL_N | FLAGVAL_Z)) == 0; + case 15: cznv &= (FLAGVAL_N | FLAGVAL_Z | FLAGVAL_V); /* ZFLG || (NFLG != VFLG) LE */ + return (((cznv << (FLAGBIT_N - FLAGBIT_V)) ^ cznv) & (FLAGVAL_N | FLAGVAL_Z)) != 0; +#else + case 12: return (((cznv << (FLAGBIT_V - FLAGBIT_N)) ^ cznv) & FLAGVAL_V) == 0; /* NFLG == VFLG GE */ + case 13: return (((cznv << (FLAGBIT_V - FLAGBIT_N)) ^ cznv) & FLAGVAL_V) != 0; /* NFLG != VFLG LT */ + case 14: cznv &= (FLAGVAL_N | FLAGVAL_Z | FLAGVAL_V); /* !ZFLG && (NFLG == VFLG) GT */ + return (((cznv << (FLAGBIT_V - FLAGBIT_N)) ^ cznv) & (FLAGVAL_V | FLAGVAL_Z)) == 0; + case 15: cznv &= (FLAGVAL_N | FLAGVAL_Z | FLAGVAL_V); /* ZFLG || (NFLG != VFLG) LE */ + return (((cznv << (FLAGBIT_V - FLAGBIT_N)) ^ cznv) & (FLAGVAL_V | FLAGVAL_Z)) != 0; +#endif + } return 0; } + +#else /* !SAHF_SETO_PROFITABLE */ + +int cctrue(int cc) +{ + uae_u32 cznv = regflags.cznv; + + switch (cc) { + case 0: return 1; /* T */ + case 1: return 0; /* F */ + case 2: return (cznv & (FLAGVAL_C | FLAGVAL_Z)) == 0; /* !CFLG && !ZFLG HI */ + case 3: return (cznv & (FLAGVAL_C | FLAGVAL_Z)) != 0; /* CFLG || ZFLG LS */ + case 4: return (cznv & FLAGVAL_C) == 0; /* !CFLG CC */ + case 5: return (cznv & FLAGVAL_C) != 0; /* CFLG CS */ + case 6: return (cznv & FLAGVAL_Z) == 0; /* !ZFLG NE */ + case 7: return (cznv & FLAGVAL_Z) != 0; /* ZFLG EQ */ + case 8: return (cznv & FLAGVAL_V) == 0; /* !VFLG VC */ + case 9: return (cznv & FLAGVAL_V) != 0; /* VFLG VS */ + case 10: return (cznv & FLAGVAL_N) == 0; /* !NFLG PL */ + case 11: return (cznv & FLAGVAL_N) != 0; /* NFLG MI */ +#if FLAGBIT_N > FLAGBIT_V + case 12: return (((cznv << (FLAGBIT_N - FLAGBIT_V)) ^ cznv) & FLAGVAL_N) == 0; /* NFLG == VFLG GE */ + case 13: return (((cznv << (FLAGBIT_N - FLAGBIT_V)) ^ cznv) & FLAGVAL_N) != 0; /* NFLG != VFLG LT */ + case 14: cznv &= (FLAGVAL_N | FLAGVAL_Z | FLAGVAL_V); /* !ZFLG && (NFLG == VFLG) GT */ + return (((cznv << (FLAGBIT_N - FLAGBIT_V)) ^ cznv) & (FLAGVAL_N | FLAGVAL_Z)) == 0; + case 15: cznv &= (FLAGVAL_N | FLAGVAL_Z | FLAGVAL_V); /* ZFLG || (NFLG != VFLG) LE */ + return (((cznv << (FLAGBIT_N - FLAGBIT_V)) ^ cznv) & (FLAGVAL_N | FLAGVAL_Z)) != 0; +#else + case 12: return (((cznv << (FLAGBIT_V - FLAGBIT_N)) ^ cznv) & FLAGVAL_V) == 0; /* NFLG == VFLG GE */ + case 13: return (((cznv << (FLAGBIT_V - FLAGBIT_N)) ^ cznv) & FLAGVAL_V) != 0; /* NFLG != VFLG LT */ + case 14: cznv &= (FLAGVAL_N | FLAGVAL_Z | FLAGVAL_V); /* !ZFLG && (NFLG == VFLG) GT */ + return (((cznv << (FLAGBIT_V - FLAGBIT_N)) ^ cznv) & (FLAGVAL_V | FLAGVAL_Z)) == 0; + case 15: cznv &= (FLAGVAL_N | FLAGVAL_Z | FLAGVAL_V); /* ZFLG || (NFLG != VFLG) LE */ + return (((cznv << (FLAGBIT_V - FLAGBIT_N)) ^ cznv) & (FLAGVAL_V | FLAGVAL_Z)) != 0; +#endif + } + return 0; +} + +#endif diff --git a/od-win32/machdep/m68k.h b/od-win32/machdep/m68k.h index be00e9a5..cea10e77 100644 --- a/od-win32/machdep/m68k.h +++ b/od-win32/machdep/m68k.h @@ -10,38 +10,107 @@ /* * Machine dependent structure for holding the 68k CCR flags */ + +extern int cctrue(int cc); + +#ifndef SAHF_SETO_PROFITABLE + struct flag_struct { - unsigned int cznv; - unsigned int x; +#if defined(CPU_x86_64) + uae_u64 cznv; + uae_u64 x; +#else + uae_u32 cznv; + uae_u32 x; +#endif }; extern struct flag_struct regflags; -#if 1 -#define FLAGBIT_N 15 -#define FLAGBIT_Z 14 -#define FLAGBIT_C 8 -#define FLAGBIT_V 0 -#define FLAGBIT_X 8 -#else +/* + * The bits in the cznv field in the above structure are assigned to + * allow the easy mirroring of the x86 rFLAGS register. + * + * The 68k CZNV flags are thus assigned in cznv as: + * + * 76543210 FEDCBA98 --------- --------- + * SZxxxxxC xxxxVxxx xxxxxxxxx xxxxxxxxx + */ + #define FLAGBIT_N 7 #define FLAGBIT_Z 6 #define FLAGBIT_C 0 #define FLAGBIT_V 11 #define FLAGBIT_X 0 -#endif #define FLAGVAL_N (1 << FLAGBIT_N) -#define FLAGVAL_Z (1 << FLAGBIT_Z) +#define FLAGVAL_Z (1 << FLAGBIT_Z) #define FLAGVAL_C (1 << FLAGBIT_C) #define FLAGVAL_V (1 << FLAGBIT_V) #define FLAGVAL_X (1 << FLAGBIT_X) -#define SET_ZFLG(y) (regflags.cznv = (regflags.cznv & ~FLAGVAL_Z) | (((y) ? 1 : 0) << FLAGBIT_Z)) -#define SET_CFLG(y) (regflags.cznv = (regflags.cznv & ~FLAGVAL_C) | (((y) ? 1 : 0) << FLAGBIT_C)) -#define SET_VFLG(y) (regflags.cznv = (regflags.cznv & ~FLAGVAL_V) | (((y) ? 1 : 0) << FLAGBIT_V)) -#define SET_NFLG(y) (regflags.cznv = (regflags.cznv & ~FLAGVAL_N) | (((y) ? 1 : 0) << FLAGBIT_N)) -#define SET_XFLG(y) (regflags.x = ((y) ? 1 : 0) << FLAGBIT_X) +#define SET_ZFLG(y) (regflags.cznv = (regflags.cznv & ~FLAGVAL_Z) | (((y) & 1) << FLAGBIT_Z)) +#define SET_CFLG(y) (regflags.cznv = (regflags.cznv & ~FLAGVAL_C) | (((y) & 1) << FLAGBIT_C)) +#define SET_VFLG(y) (regflags.cznv = (regflags.cznv & ~FLAGVAL_V) | (((y) & 1) << FLAGBIT_V)) +#define SET_NFLG(y) (regflags.cznv = (regflags.cznv & ~FLAGVAL_N) | (((y) & 1) << FLAGBIT_N)) +#define SET_XFLG(y) (regflags.x = ((y) & 1) << FLAGBIT_X) + +#define GET_ZFLG() ((regflags.cznv >> FLAGBIT_Z) & 1) +#define GET_CFLG() ((regflags.cznv >> FLAGBIT_C) & 1) +#define GET_VFLG() ((regflags.cznv >> FLAGBIT_V) & 1) +#define GET_NFLG() ((regflags.cznv >> FLAGBIT_N) & 1) +#define GET_XFLG() ((regflags.x >> FLAGBIT_X) & 1) + +#define CLEAR_CZNV() (regflags.cznv = 0) +#define GET_CZNV() (regflags.cznv) +#define IOR_CZNV(X) (regflags.cznv |= (X)) +#define SET_CZNV(X) (regflags.cznv = (X)) + +#define COPY_CARRY() (regflags.x = regflags.cznv >> (FLAGBIT_C - FLAGBIT_X)) + +#else /* !SAHF_SETO_PROFITABLE */ + + /* + * Machine dependent structure for holding the 68k CCR flags + */ +struct flag_struct { + uae_u32 cznv; + uae_u32 x; +}; + +extern struct flag_struct regflags; + +/* + * The bits in the cznv field in the above structure are assigned to + * allow the easy mirroring of the x86 condition flags. (For example, + * from the AX register - the x86 overflow flag can be copied to AL + * with a setto %AL instr and the other flags copied to AH with an + * lahf instr). + * + * The 68k CZNV flags are thus assigned in cznv as: + * + * <--AL--> <--AH--> + * 76543210 FEDCBA98 --------- --------- + * xxxxxxxV NZxxxxxC xxxxxxxxx xxxxxxxxx + */ + +#define FLAGBIT_N 15 +#define FLAGBIT_Z 14 +#define FLAGBIT_C 8 +#define FLAGBIT_V 0 +#define FLAGBIT_X 0 /* must be in position 0 for duplicate_carry() to work */ + +#define FLAGVAL_N (1 << FLAGBIT_N) +#define FLAGVAL_Z (1 << FLAGBIT_Z) +#define FLAGVAL_C (1 << FLAGBIT_C) +#define FLAGVAL_V (1 << FLAGBIT_V) +#define FLAGVAL_X (1 << FLAGBIT_X) + +#define SET_ZFLG(y) (regflags.cznv = (((uae_u32)regflags.cznv) & ~FLAGVAL_Z) | (((y) & 1) << FLAGBIT_Z)) +#define SET_CFLG(y) (regflags.cznv = (((uae_u32)regflags.cznv) & ~FLAGVAL_C) | (((y) & 1) << FLAGBIT_C)) +#define SET_VFLG(y) (regflags.cznv = (((uae_u32)regflags.cznv) & ~FLAGVAL_V) | (((y) & 1) << FLAGBIT_V)) +#define SET_NFLG(y) (regflags.cznv = (((uae_u32)regflags.cznv) & ~FLAGVAL_N) | (((y) & 1) << FLAGBIT_N)) +#define SET_XFLG(y) (regflags.x = ((y) & 1) << FLAGBIT_X) #define GET_ZFLG() ((regflags.cznv >> FLAGBIT_Z) & 1) #define GET_CFLG() ((regflags.cznv >> FLAGBIT_C) & 1) @@ -49,11 +118,11 @@ extern struct flag_struct regflags; #define GET_NFLG() ((regflags.cznv >> FLAGBIT_N) & 1) #define GET_XFLG() ((regflags.x >> FLAGBIT_X) & 1) -#define CLEAR_CZNV() (regflags.cznv = 0) -#define GET_CZNV() (regflags.cznv) -#define IOR_CZNV(X) (regflags.cznv |= (X)) -#define SET_CZNV(X) (regflags.cznv = (X)) +#define CLEAR_CZNV() (regflags.cznv = 0) +#define GET_CZNV() (regflags.cznv) +#define IOR_CZNV(X) (regflags.cznv |= (X)) +#define SET_CZNV(X) (regflags.cznv = (X)) -#define COPY_CARRY() (regflags.x = regflags.cznv) +#define COPY_CARRY() (regflags.x = regflags.cznv >> (FLAGBIT_C - FLAGBIT_X)) -extern int cctrue(int cc); +#endif diff --git a/od-win32/machdep/maccess.h b/od-win32/machdep/maccess.h index 2a5223f7..1b3cea31 100644 --- a/od-win32/machdep/maccess.h +++ b/od-win32/machdep/maccess.h @@ -50,6 +50,26 @@ STATIC_INLINE void do_put_mem_byte(uae_u8 *a, uae_u8 v) *a = v; } +STATIC_INLINE uae_u64 do_byteswap_64(uae_u64 v) +{ + return _byteswap_uint64(v); +} + +STATIC_INLINE uae_u32 do_byteswap_32(uae_u32 v) +{ + return _byteswap_ulong(v); +} + +STATIC_INLINE uae_u16 do_byteswap_16(uae_u16 v) +{ + return _byteswap_ushort(v); +} + +STATIC_INLINE uae_u32 do_get_mem_word_unswapped(uae_u16 *a) +{ + return *a; +} + #define call_mem_get_func(func, addr) ((*func)(addr)) #define call_mem_put_func(func, addr, v) ((*func)(addr, v)) diff --git a/od-win32/sysconfig.h b/od-win32/sysconfig.h index ef2692b3..38cb09a5 100644 --- a/od-win32/sysconfig.h +++ b/od-win32/sysconfig.h @@ -13,7 +13,7 @@ #define DRIVESOUND #define GFXFILTER #define X86_MSVC_ASSEMBLY -#define OPTIMIZED_FLAGS +//#define OPTIMIZED_FLAGS #define MSVC_LONG_DOUBLE #ifndef __i386__ #define __i386__ @@ -30,6 +30,8 @@ #define AUTOCONFIG /* autoconfig support, fast ram, harddrives etc.. */ #define JIT /* JIT compiler support */ #define USE_JIT_FPU +#define NOFLAGS_SUPPORT +//#define HAVE_GET_WORD_UNSWAPPED #define NATMEM_OFFSET natmem_offset #define USE_NORMAL_CALLING_CONVENTION 0 #define USE_X86_FPUCW 1 diff --git a/readcpu.cpp b/readcpu.cpp index ddceee21..7bdaa536 100644 --- a/readcpu.cpp +++ b/readcpu.cpp @@ -206,30 +206,41 @@ static void build_insn (int insn) { int find = -1; int variants; - int isjmp = 0; struct instr_def id; const TCHAR *opcstr; - int i; + int i, n; int flaglive = 0, flagdead = 0; + int cflow = 0; id = defs68k[insn]; - /* Note: We treat anything with unknown flags as a jump. That - is overkill, but "the programmer" was lazy quite often, and - *this* programmer can't be bothered to work out what can and - can't trap. Usually, this will be overwritten with the gencomp - based information, anyway. */ + // Control flow information + cflow = id.cflow; + + // Mask of flags set/used + unsigned char flags_set(0), flags_used(0); + + for (i = 0, n = 4; i < 5; i++, n--) { + switch (id.flaginfo[i].flagset) { + case fa_unset: case fa_isjmp: break; + default: flags_set |= (1 << n); + } + + switch (id.flaginfo[i].flaguse) { + case fu_unused: case fu_isjmp: break; + default: flags_used |= (1 << n); + } + } for (i = 0; i < 5; i++) { - switch (id.flaginfo[i].flagset){ + switch (id.flaginfo[i].flagset) { case fa_unset: break; - case fa_isjmp: isjmp = 1; break; - case fa_isbranch: isjmp = 1; break; + case fa_isjmp: break; case fa_zero: flagdead |= 1 << i; break; case fa_one: flagdead |= 1 << i; break; case fa_dontcare: flagdead |= 1 << i; break; - case fa_unknown: isjmp = 1; flagdead = -1; goto out1; + case fa_unknown: flagdead = -1; goto out1; case fa_set: flagdead |= 1 << i; break; } } @@ -238,12 +249,13 @@ out1: for (i = 0; i < 5; i++) { switch (id.flaginfo[i].flaguse) { case fu_unused: break; - case fu_isjmp: isjmp = 1; flaglive |= 1 << i; break; - case fu_maybecc: isjmp = 1; flaglive |= 1 << i; break; - case fu_unknown: isjmp = 1; flaglive |= 1 << i; break; + case fu_isjmp: flaglive |= 1 << i; break; + case fu_maybecc: flaglive |= 1 << i; break; + case fu_unknown: flaglive = -1; goto out2; case fu_used: flaglive |= 1 << i; break; } } +out2: opcstr = id.opcstr; for (variants = 0; variants < (1 << id.n_variable); variants++) { @@ -353,6 +365,7 @@ out1: /* parse the source address */ usesrc = 1; + switch (opcstr[pos++]) { case 'D': srcmode = Dreg; @@ -365,6 +378,7 @@ out1: case 'A': srcmode = Areg; switch (opcstr[pos++]) { + case 'l': srcmode = absl; break; case 'r': srcreg = bitval[bitr]; srcgather = 1; srcpos = bitpos[bitr]; break; case 'R': srcreg = bitval[bitR]; srcgather = 1; srcpos = bitpos[bitR]; break; default: abort(); @@ -375,9 +389,6 @@ out1: case 'a': srcmode = Aind; pos++; break; } break; - case 'L': - srcmode = absl; - break; case '#': switch (opcstr[pos++]) { case 'z': srcmode = imm; break; @@ -423,8 +434,16 @@ out1: srcpos = bitpos[bitK]; } break; + case 'E': srcmode = immi; srcreg = bitval[bitE]; + if (CPU_EMU_SIZE < 5) { // gb-- what is CPU_EMU_SIZE used for ?? + /* 1..255 */ + srcgather = 1; + srctype = 6; + srcpos = bitpos[bitE]; + } + break; case 'p': srcmode = immi; srcreg = bitval[bitK]; - if (CPU_EMU_SIZE < 5) { + if (CPU_EMU_SIZE < 5) { // gb-- what is CPU_EMU_SIZE used for ?? /* 0..3 */ srcgather = 1; srctype = 7; @@ -561,21 +580,17 @@ out1: case 'A': destmode = Areg; switch (opcstr[pos++]) { + case 'l': destmode = absl; break; case 'r': destreg = bitval[bitr]; dstgather = 1; dstpos = bitpos[bitr]; break; case 'R': destreg = bitval[bitR]; dstgather = 1; dstpos = bitpos[bitR]; break; case 'x': destreg = 0; dstgather = 0; dstpos = 0; break; default: abort(); } - if (dstpos < 0 || dstpos >= 32) - abort (); switch (opcstr[pos]) { case 'p': destmode = Apdi; pos++; break; case 'P': destmode = Aipi; pos++; break; } break; - case 'L': - destmode = absl; - break; case '#': switch (opcstr[pos++]) { case 'z': destmode = imm; break; @@ -763,27 +778,47 @@ endofline: table68k[opc].flaginfo[i].flaguse = id.flaginfo[i].flaguse; } #endif - table68k[opc].flagdead = flagdead; - table68k[opc].flaglive = flaglive; - table68k[opc].isjmp = isjmp; -nomatch: - /* FOO! */; - } -} + // Fix flags used information for Scc, Bcc, TRAPcc, DBcc instructions + if (table68k[opc].mnemo == i_Scc + || table68k[opc].mnemo == i_Bcc + || table68k[opc].mnemo == i_DBcc + || table68k[opc].mnemo == i_TRAPcc + ) { + switch (table68k[opc].cc) { + // CC mask: XNZVC + // 8421 + case 0: flags_used = 0x00; break; /* T */ + case 1: flags_used = 0x00; break; /* F */ + case 2: flags_used = 0x05; break; /* HI */ + case 3: flags_used = 0x05; break; /* LS */ + case 4: flags_used = 0x01; break; /* CC */ + case 5: flags_used = 0x01; break; /* CS */ + case 6: flags_used = 0x04; break; /* NE */ + case 7: flags_used = 0x04; break; /* EQ */ + case 8: flags_used = 0x02; break; /* VC */ + case 9: flags_used = 0x02; break; /* VS */ + case 10:flags_used = 0x08; break; /* PL */ + case 11:flags_used = 0x08; break; /* MI */ + case 12:flags_used = 0x0A; break; /* GE */ + case 13:flags_used = 0x0A; break; /* LT */ + case 14:flags_used = 0x0E; break; /* GT */ + case 15:flags_used = 0x0E; break; /* LE */ + } + } -void read_table68k (void) -{ - int i; +#if 1 + /* gb-- flagdead and flaglive would not have correct information */ + table68k[opc].flagdead = flags_set; + table68k[opc].flaglive = flags_used; +#else + table68k[opc].flagdead = flagdead; + table68k[opc].flaglive = flaglive; +#endif + table68k[opc].cflow = cflow; - free (table68k); - table68k = xmalloc (struct instr, 65536); - for (i = 0; i < 65536; i++) { - table68k[i].mnemo = i_ILLG; - table68k[i].handler = -1; - } - for (i = 0; i < n_defs68k; i++) { - build_insn (i); + nomatch: + /* FOO! */; } } @@ -812,6 +847,8 @@ static void handle_merges (long int opcode) smsk = 7; sbitdst = 8; break; case 5: smsk = 63; sbitdst = 64; break; + case 6: + smsk = 255; sbitdst = 256; break; case 7: smsk = 3; sbitdst = 4; break; default: @@ -920,3 +957,25 @@ bool opcode_loop_mode(uae_u16 opcode) } return loopmode; } + +void init_table68k(void) +{ + int i; + + free(table68k); + table68k = xmalloc(struct instr, 65536); + for (i = 0; i < 65536; i++) { + table68k[i].mnemo = i_ILLG; + table68k[i].handler = -1; + } + for (i = 0; i < n_defs68k; i++) { + build_insn(i); + } + do_merges(); +} + +void exit_table68k(void) +{ + free(table68k); + table68k = NULL; +} diff --git a/table68k b/table68k index 0ec4ffb6..79f825c7 100644 --- a/table68k +++ b/table68k @@ -4,6 +4,7 @@ % C: condition codes, except F % f: direction % i: immediate +% E: immediate, except 00 (Aranym only, EmulOp instruction) % I: immediate, except 00 and ff % j: immediate 1..8 % J: immediate 0..15 @@ -53,467 +54,480 @@ % 0 means flag reset % 1 means flag set % ? means programmer was too lazy to check or instruction may trap -% + means instruction is conditional branch -% everything else means flag set/used -% / means instruction is unconditional branch/call +% + means instruction is conditional branch (ignored, only for sync) +% / means instruction is unconditional branch/call (ignored, only for sync) % x means flag is unknown and well-behaved programs shouldn't check it +% everything else means flag set/used +% +% Control flow +% two letters, combination of +% - nothing +% T the instruction may trap or cause an exception +% B branch instruction +% J jump instruction +% R return instruction +% % srcaddr status destaddr status : % bitmasks of % 1 means fetched % 2 means stored % 4 means jump offset % 8 means jump address +% % instruction % optional line feed and 68030 Head/Tail/Cycles/ea calculation % -0000 0000 0011 1100:000:XNZVC:XNZVC:10: ORSR.B #1 -0000 0000 0111 1100:002:?????:?????:10: ORSR.W #1 -0000 0zz0 11ss sSSS:250:?????:?????:11: CHK2.z #1,s[!Dreg,Areg,Aipi,Apdi,Immd] +0000 0000 0011 1100:000:XNZVC:XNZVC:--:10: ORSR.B #1 +0000 0000 0111 1100:002:XNZVC:XNZVC:T-:10: ORSR.W #1 +0000 0zz0 11ss sSSS:250:-?Z?C:-----:T-:11: CHK2.z #1,s[!Dreg,Areg,Aipi,Apdi,Immd] -0000 0000 zzdd dDDD:000:-NZ00:-----:13: OR.z #z,d[Dreg] +0000 0000 zzdd dDDD:000:-NZ00:-----:--:13: OR.z #z,d[Dreg] - 2 0 2 fiea -0000 0000 zzdd dDDD:000:-NZ00:-----:13: OR.z #z,d[!Areg,Dreg] +0000 0000 zzdd dDDD:000:-NZ00:-----:--:13: OR.z #z,d[!Areg,Dreg] - 0 1 3 fiea -0000 0010 0011 1100:000:XNZVC:XNZVC:10: ANDSR.B #1 -0000 0010 0111 1100:002:?????:?????:10: ANDSR.W #1 +0000 0010 0011 1100:000:XNZVC:XNZVC:--:10: ANDSR.B #1 +0000 0010 0111 1100:002:XNZVC:XNZVC:T-:10: ANDSR.W #1 -0000 0010 zzdd dDDD:000:-NZ00:-----:13: AND.z #z,d[Dreg] +0000 0010 zzdd dDDD:000:-NZ00:-----:--:13: AND.z #z,d[Dreg] - 2 0 2 fiea -0000 0010 zzdd dDDD:000:-NZ00:-----:13: AND.z #z,d[!Areg,Dreg] +0000 0010 zzdd dDDD:000:-NZ00:-----:--:13: AND.z #z,d[!Areg,Dreg] - 0 1 3 fiea -0000 0100 zzdd dDDD:000:XNZVC:-----:13: SUB.z #z,d[Dreg] +0000 0100 zzdd dDDD:000:XNZVC:-----:--:13: SUB.z #z,d[Dreg] - 2 0 2 fiea -0000 0100 zzdd dDDD:000:XNZVC:-----:13: SUB.z #z,d[!Areg,Dreg] +0000 0100 zzdd dDDD:000:XNZVC:-----:--:13: SUB.z #z,d[!Areg,Dreg] - 0 1 3 fiea -0000 0110 zzdd dDDD:000:XNZVC:-----:13: ADD.z #z,d[Dreg] +0000 0110 zzdd dDDD:000:XNZVC:-----:--:13: ADD.z #z,d[Dreg] - 2 0 2 fiea -0000 0110 zzdd dDDD:000:XNZVC:-----:13: ADD.z #z,d[!Areg,Dreg] +0000 0110 zzdd dDDD:000:XNZVC:-----:--:13: ADD.z #z,d[!Areg,Dreg] - 0 1 3 fiea -0000 0110 11ss sSSS:230:?????:?????:10: CALLM s[!Dreg,Areg,Aipi,Apdi,Immd] -0000 0110 11ss sSSS:230:?????:?????:10: RTM s[Dreg,Areg] +0000 0110 11ss sSSS:230:-----:XNZVC:--:10: CALLM s[!Dreg,Areg,Aipi,Apdi,Immd] +0000 0110 11ss sSSS:230:XNZVC:-----:-R:10: RTM s[Dreg,Areg] -0000 1000 00ss sSSS:000:--Z--:-----:11: BTST #1,s[Dreg] +0000 1000 00ss sSSS:000:--Z--:-----:--:11: BTST #1,s[Dreg] - 4 0 4 -0000 1000 00ss sSSS:000:--Z--:-----:11: BTST #1,s[!Areg,Dreg,Immd] +0000 1000 00ss sSSS:000:--Z--:-----:--:11: BTST #1,s[!Areg,Dreg,Immd] - 0 0 4 fiea -0000 1000 01ss sSSS:000:--Z--:-----:13: BCHG #1,s[Dreg] +0000 1000 01ss sSSS:000:--Z--:-----:--:13: BCHG #1,s[Dreg] - 6 0 6 -0000 1000 01ss sSSS:000:--Z--:-----:13: BCHG #1,s[!Areg,Dreg,Immd,PC8r,PC16] +0000 1000 01ss sSSS:000:--Z--:-----:--:13: BCHG #1,s[!Areg,Dreg,Immd,PC8r,PC16] - 0 0 6 fiea -0000 1000 10ss sSSS:000:--Z--:-----:13: BCLR #1,s[Dreg] +0000 1000 10ss sSSS:000:--Z--:-----:--:13: BCLR #1,s[Dreg] - 6 0 6 -0000 1000 10ss sSSS:000:--Z--:-----:13: BCLR #1,s[!Areg,Dreg,Immd,PC8r,PC16] +0000 1000 10ss sSSS:000:--Z--:-----:--:13: BCLR #1,s[!Areg,Dreg,Immd,PC8r,PC16] - 0 0 6 fiea -0000 1000 11ss sSSS:000:--Z--:-----:13: BSET #1,s[Dreg] +0000 1000 11ss sSSS:000:--Z--:-----:--:13: BSET #1,s[Dreg] - 6 0 6 -0000 1000 11ss sSSS:000:--Z--:-----:13: BSET #1,s[!Areg,Dreg,Immd,PC8r,PC16] +0000 1000 11ss sSSS:000:--Z--:-----:--:13: BSET #1,s[!Areg,Dreg,Immd,PC8r,PC16] - 0 0 6 fiea -0000 1010 0011 1100:000:XNZVC:XNZVC:10: EORSR.B #1 -0000 1010 0111 1100:002:?????:?????:10: EORSR.W #1 +0000 1010 0011 1100:000:XNZVC:XNZVC:--:10: EORSR.B #1 +0000 1010 0111 1100:002:XNZVC:XNZVC:T-:10: EORSR.W #1 -0000 1010 zzdd dDDD:000:-NZ00:-----:13: EOR.z #z,d[Dreg] +0000 1010 zzdd dDDD:000:-NZ00:-----:--:13: EOR.z #z,d[Dreg] - 2 0 2 fiea -0000 1010 zzdd dDDD:000:-NZ00:-----:13: EOR.z #z,d[!Areg,Dreg] +0000 1010 zzdd dDDD:000:-NZ00:-----:--:13: EOR.z #z,d[!Areg,Dreg] - 0 1 3 fiea -0000 1100 zzss sSSS:000:-NZVC:-----:11: CMP.z #z,s[Dreg] +0000 1100 zzss sSSS:000:-NZVC:-----:--:11: CMP.z #z,s[Dreg] - 2 0 2 fiea -0000 1100 zzss sSSS:000:-NZVC:-----:11: CMP.z #z,s[!Areg,Dreg,Immd,PC8r,PC16] +0000 1100 zzss sSSS:000:-NZVC:-----:--:11: CMP.z #z,s[!Areg,Dreg,Immd,PC8r,PC16] - 0 0 2 fiea -0000 1100 zzss sSSS:200:-NZVC:-----:11: CMP.z #z,s[PC8r,PC16] +0000 1100 zzss sSSS:200:-NZVC:-----:--:11: CMP.z #z,s[PC8r,PC16] - 0 0 2 fiea -0000 1010 11ss sSSS:200:?????:?????:13: CAS.B #1,s[!Dreg,Areg,Immd,PC8r,PC16] -0000 1100 11ss sSSS:200:?????:?????:13: CAS.W #1,s[!Dreg,Areg,Immd,PC8r,PC16] -0000 1100 1111 1100:250:?????:?????:10: CAS2.W #2 -0000 1110 zzss sSSS:102:?????:?????:13: MOVES.z #1,s[!Dreg,Areg,Immd,PC8r,PC16] -0000 1110 11ss sSSS:200:?????:?????:13: CAS.L #1,s[!Dreg,Areg,Immd,PC8r,PC16] -0000 1110 1111 1100:250:?????:?????:10: CAS2.L #2 +0000 1010 11ss sSSS:200:-NZVC:-----:--:13: CAS.B #1,s[!Dreg,Areg,Immd,PC8r,PC16] +0000 1100 11ss sSSS:200:-NZVC:-----:--:13: CAS.W #1,s[!Dreg,Areg,Immd,PC8r,PC16] +0000 1100 1111 1100:250:-NZVC:-----:--:10: CAS2.W #2 +0000 1110 zzss sSSS:102:-----:-----:T-:13: MOVES.z #1,s[!Dreg,Areg,Immd,PC8r,PC16] +0000 1110 11ss sSSS:200:-NZVC:-----:--:13: CAS.L #1,s[!Dreg,Areg,Immd,PC8r,PC16] +0000 1110 1111 1100:250:-NZVC:-----:--:10: CAS2.L #2 -0000 rrr1 00dd dDDD:050:-----:-----:12: MVPMR.W d[Areg-Ad16],Dr -0000 rrr1 01dd dDDD:050:-----:-----:12: MVPMR.L d[Areg-Ad16],Dr -0000 rrr1 10dd dDDD:050:-----:-----:12: MVPRM.W Dr,d[Areg-Ad16] -0000 rrr1 11dd dDDD:050:-----:-----:12: MVPRM.L Dr,d[Areg-Ad16] +0000 rrr1 00dd dDDD:050:-----:-----:--:12: MVPMR.W d[Areg-Ad16],Dr +0000 rrr1 01dd dDDD:050:-----:-----:--:12: MVPMR.L d[Areg-Ad16],Dr +0000 rrr1 10dd dDDD:050:-----:-----:--:12: MVPRM.W Dr,d[Areg-Ad16] +0000 rrr1 11dd dDDD:050:-----:-----:--:12: MVPRM.L Dr,d[Areg-Ad16] -0000 rrr1 00ss sSSS:000:--Z--:-----:11: BTST Dr,s[Dreg] +0000 rrr1 00ss sSSS:000:--Z--:-----:--:11: BTST Dr,s[Dreg] - 4 0 4 -0000 rrr1 00ss sSSS:000:--Z--:-----:11: BTST Dr,s[!Areg,Dreg] +0000 rrr1 00ss sSSS:000:--Z--:-----:--:11: BTST Dr,s[!Areg,Dreg] - 0 0 4 fea -0000 rrr1 01ss sSSS:000:--Z--:-----:13: BCHG Dr,s[Dreg] +0000 rrr1 01ss sSSS:000:--Z--:-----:--:13: BCHG Dr,s[Dreg] - 6 0 6 -0000 rrr1 01ss sSSS:000:--Z--:-----:13: BCHG Dr,s[!Areg,Dreg,Immd,PC8r,PC16] +0000 rrr1 01ss sSSS:000:--Z--:-----:--:13: BCHG Dr,s[!Areg,Dreg,Immd,PC8r,PC16] - 0 0 6 fea -0000 rrr1 10ss sSSS:000:--Z--:-----:13: BCLR Dr,s[Dreg] +0000 rrr1 10ss sSSS:000:--Z--:-----:--:13: BCLR Dr,s[Dreg] - 6 0 6 -0000 rrr1 10ss sSSS:000:--Z--:-----:13: BCLR Dr,s[!Areg,Dreg,Immd,PC8r,PC16] +0000 rrr1 10ss sSSS:000:--Z--:-----:--:13: BCLR Dr,s[!Areg,Dreg,Immd,PC8r,PC16] - 0 0 6 fea -0000 rrr1 11ss sSSS:000:--Z--:-----:13: BSET Dr,s[Dreg] +0000 rrr1 11ss sSSS:000:--Z--:-----:--:13: BSET Dr,s[Dreg] - 6 0 6 -0000 rrr1 11ss sSSS:000:--Z--:-----:13: BSET Dr,s[!Areg,Dreg,Immd,PC8r,PC16] +0000 rrr1 11ss sSSS:000:--Z--:-----:--:13: BSET Dr,s[!Areg,Dreg,Immd,PC8r,PC16] - 0 0 6 fea % Move cycles are special cased in gencpu.c -0001 DDDd ddss sSSS:000:-NZ00:-----:12: MOVE.B s,d[!Areg] -0011 DDDd ddss sSSS:000:-----:-----:12: MOVEA.W s,d[Areg] -0011 DDDd ddss sSSS:000:-NZ00:-----:12: MOVE.W s,d[!Areg] -0010 DDDd ddss sSSS:000:-----:-----:12: MOVEA.L s,d[Areg] -0010 DDDd ddss sSSS:000:-NZ00:-----:12: MOVE.L s,d[!Areg] +0001 DDDd ddss sSSS:000:-NZ00:-----:--:12: MOVE.B s,d[!Areg] +0011 DDDd ddss sSSS:000:-----:-----:--:12: MOVEA.W s,d[Areg] +0011 DDDd ddss sSSS:000:-NZ00:-----:--:12: MOVE.W s,d[!Areg] +0010 DDDd ddss sSSS:000:-----:-----:--:12: MOVEA.L s,d[Areg] +0010 DDDd ddss sSSS:000:-NZ00:-----:--:12: MOVE.L s,d[!Areg] -0100 0000 zzdd dDDD:000:XxZxC:X-Z--:30: NEGX.z d[Dreg] +0100 0000 zzdd dDDD:000:XNZVC:X-Z--:--:30: NEGX.z d[Dreg] - 2 0 2 -0100 0000 zzdd dDDD:000:XxZxC:X-Z--:30: NEGX.z d[!Areg,Dreg] +0100 0000 zzdd dDDD:000:XNZVC:X-Z--:--:30: NEGX.z d[!Areg,Dreg] - 0 1 3 fea -0100 0000 11dd dDDD:001:?????:?????:10: MVSR2.W d[Dreg] +0100 0000 11dd dDDD:001:-----:XNZVC:T-:10: MVSR2.W d[Dreg] - 2 0 4 -0100 0000 11dd dDDD:001:?????:?????:10: MVSR2.W d[!Areg,Dreg] +0100 0000 11dd dDDD:001:-----:XNZVC:T-:10: MVSR2.W d[!Areg,Dreg] - 2 0 4 cea -0100 0010 zzdd dDDD:000:-0100:-----:20: CLR.z d[Dreg] +0100 0010 zzdd dDDD:000:-0100:-----:--:20: CLR.z d[Dreg] - 2 0 2 -0100 0010 zzdd dDDD:000:-0100:-----:20: CLR.z d[!Areg,Dreg] +0100 0010 zzdd dDDD:000:-0100:-----:--:20: CLR.z d[!Areg,Dreg] - 0 1 3 cea -0100 0010 11dd dDDD:100:?????:?????:10: MVSR2.B d[Dreg] +0100 0010 11dd dDDD:100:-----:XNZVC:--:10: MVSR2.B d[Dreg] - 2 0 4 -0100 0010 11dd dDDD:100:?????:?????:10: MVSR2.B d[!Areg,Dreg] +0100 0010 11dd dDDD:100:-----:XNZVC:--:10: MVSR2.B d[!Areg,Dreg] - 2 0 4 cea -0100 0100 zzdd dDDD:000:XNZVC:-----:30: NEG.z d[Dreg] +0100 0100 zzdd dDDD:000:XNZVC:-----:--:30: NEG.z d[Dreg] - 2 0 2 -0100 0100 zzdd dDDD:000:XNZVC:-----:30: NEG.z d[!Areg,Dreg] +0100 0100 zzdd dDDD:000:XNZVC:-----:--:30: NEG.z d[!Areg,Dreg] - 0 1 3 fea -0100 0100 11ss sSSS:000:XNZVC:-----:10: MV2SR.B s[Dreg] +0100 0100 11ss sSSS:000:XNZVC:-----:--:10: MV2SR.B s[Dreg] - 4 0 4 -0100 0100 11ss sSSS:000:XNZVC:-----:10: MV2SR.B s[!Areg,Dreg] +0100 0100 11ss sSSS:000:XNZVC:-----:--:10: MV2SR.B s[!Areg,Dreg] - 0 0 4 fea -0100 0110 zzdd dDDD:000:-NZ00:-----:30: NOT.z d[Dreg] +0100 0110 zzdd dDDD:000:-NZ00:-----:--:30: NOT.z d[Dreg] - 2 0 2 -0100 0110 zzdd dDDD:000:-NZ00:-----:30: NOT.z d[!Areg,Dreg] +0100 0110 zzdd dDDD:000:-NZ00:-----:--:30: NOT.z d[!Areg,Dreg] - 0 1 3 fea -0100 0110 11ss sSSS:002:?????:?????:10: MV2SR.W s[!Areg] +0100 0110 11ss sSSS:002:XNZVC:XNZVC:T-:10: MV2SR.W s[!Areg] - 0 0 8 fea -0100 1000 0000 1rrr:200:-----:-----:31: LINK.L Ar,#2 +0100 1000 0000 1rrr:200:-----:-----:--:31: LINK.L Ar,#2 - 2 0 6 -0100 1000 00dd dDDD:000:X?Z?C:X-Z--:30: NBCD.B d[!Areg] +0100 1000 00dd dDDD:000:X?Z?C:X-Z--:--:30: NBCD.B d[!Areg] - 0 0 6 -0100 1000 0100 1kkk:100:?????:?????:10: BKPT #k +0100 1000 0100 1kkk:100:-----:-----:T-:10: BKPT #k -0100 1000 01ss sSSS:000:-NZ00:-----:30: SWAP.W s[Dreg] +0100 1000 01ss sSSS:000:-NZ00:-----:--:30: SWAP.W s[Dreg] - 4 0 4 -0100 1000 01ss sSSS:000:-----:-----:00: PEA.L s[!Dreg,Areg,Aipi,Apdi,Immd] +0100 1000 01ss sSSS:000:-----:-----:--:00: PEA.L s[!Dreg,Areg,Aipi,Apdi,Immd] - 0 2 4 cea -0100 1000 10dd dDDD:000:-NZ00:-----:30: EXT.W d[Dreg] +0100 1000 10dd dDDD:000:-NZ00:-----:--:30: EXT.W d[Dreg] - 4 0 4 -0100 1000 10dd dDDD:000:-----:-----:02: MVMLE.W #1,d[!Dreg,Areg,Aipi] +0100 1000 10dd dDDD:000:-----:-----:--:02: MVMLE.W #1,d[!Dreg,Areg,Aipi] -0100 1000 11dd dDDD:000:-NZ00:-----:30: EXT.L d[Dreg] +0100 1000 11dd dDDD:000:-NZ00:-----:--:30: EXT.L d[Dreg] - 4 0 4 -0100 1000 11dd dDDD:000:-----:-----:02: MVMLE.L #1,d[!Dreg,Areg,Aipi] +0100 1000 11dd dDDD:000:-----:-----:--:02: MVMLE.L #1,d[!Dreg,Areg,Aipi] -0100 1001 11dd dDDD:200:-NZ00:-----:30: EXT.B d[Dreg] +0100 1001 11dd dDDD:200:-NZ00:-----:--:30: EXT.B d[Dreg] - 4 0 4 -0100 1010 zzss sSSS:000:-NZ00:-----:10: TST.z s[Dreg] +0100 1010 zzss sSSS:000:-NZ00:-----:--:10: TST.z s[Dreg] - 0 0 2 -0100 1010 zzss sSSS:000:-NZ00:-----:10: TST.z s[!Areg,Dreg,PC16,PC8r,Immd] +0100 1010 zzss sSSS:000:-NZ00:-----:--:10: TST.z s[!Areg,Dreg,PC16,PC8r,Immd] - 0 0 2 fea -0100 1010 zzss sSSS:200:-NZ00:-----:10: TST.z s[Areg,PC16,PC8r,Immd] +0100 1010 zzss sSSS:200:-NZ00:-----:--:10: TST.z s[Areg,PC16,PC8r,Immd] - 0 0 2 fea -0100 1010 11dd dDDD:000:?????:?????:30: TAS.B d[Dreg] +0100 1010 11dd dDDD:000:-NZ00:-----:--:30: TAS.B d[Dreg] - 0 0 2 -0100 1010 11dd dDDD:000:?????:?????:30: TAS.B d[!Areg,Dreg] +0100 1010 11dd dDDD:000:-NZ00:-----:--:30: TAS.B d[!Areg,Dreg] - 0 0 2 fea -0100 1010 1111 1100:000:?????:?????:00: ILLEGAL +0100 1010 1111 1100:000:-----:-----:T-:00: ILLEGAL -0100 1100 00ss sSSS:200:-NZVC:-----:13: MULL.L #1,s[!Areg] +0100 1100 00ss sSSS:200:-NZVC:-----:--:13: MULL.L #1,s[!Areg] - 2 0 30 fiea -0100 1100 01ss sSSS:200:?????:?????:13: DIVL.L #1,s[!Areg] +0100 1100 01ss sSSS:200:-NZV0:-----:T-:13: DIVL.L #1,s[!Areg] - 0 0 50 fiea -0100 1100 10ss sSSS:000:-----:-----:01: MVMEL.W #1,s[!Dreg,Areg,Apdi,Immd] -0100 1100 11ss sSSS:000:-----:-----:01: MVMEL.L #1,s[!Dreg,Areg,Apdi,Immd] -0100 1110 0100 JJJJ:000:-----:XNZVC:10: TRAP #J +0100 1100 10ss sSSS:000:-----:-----:--:01: MVMEL.W #1,s[!Dreg,Areg,Apdi,Immd] +0100 1100 11ss sSSS:000:-----:-----:--:01: MVMEL.L #1,s[!Dreg,Areg,Apdi,Immd] +0100 1110 0100 JJJJ:000:-----:XNZVC:--:10: TRAP #J -0100 1110 0101 0rrr:000:-----:-----:31: LINK.W Ar,#1 +0100 1110 0101 0rrr:000:-----:-----:--:31: LINK.W Ar,#1 - 0 0 4 -0100 1110 0101 1rrr:000:-----:-----:30: UNLK.L Ar +0100 1110 0101 1rrr:000:-----:-----:--:30: UNLK.L Ar - 0 0 5 -0100 1110 0110 0rrr:002:-----:-----:10: MVR2USP.L Ar +0100 1110 0110 0rrr:002:-----:-----:T-:10: MVR2USP.L Ar - 4 0 4 -0100 1110 0110 1rrr:002:-----:-----:20: MVUSP2R.L Ar +0100 1110 0110 1rrr:002:-----:-----:T-:20: MVUSP2R.L Ar - 4 0 4 -0100 1110 0111 0000:002:-----:-----:00: RESET +0100 1110 0111 0000:002:-----:-----:T-:00: RESET - 0 0 518 -0100 1110 0111 0001:000:-----:-----:00: NOP +0100 1110 0111 0001:000:-----:-----:--:00: NOP - 0 0 2 -0100 1110 0111 0010:002:XNZVC:-----:10: STOP #1 +0100 1110 0111 0010:002:XNZVC:-----:T-:10: STOP #1 - 0 0 8 -0100 1110 0111 0011:002:XNZVC:-----:00: RTE +0100 1110 0111 0011:002:XNZVC:-----:TR:00: RTE - 1 9 18 -0100 1110 0111 0100:100:?????:?????:10: RTD #1 +0100 1110 0111 0100:100:-----:-----:-R:10: RTD #1 - 2 0 10 -0100 1110 0111 0101:000:-----:-----:00: RTS +0100 1110 0111 0101:000:-----:-----:-R:00: RTS - 1 0 9 -0100 1110 0111 0110:000:-----:XNZVC:00: TRAPV +0100 1110 0111 0110:000:-----:XNZVC:T-:00: TRAPV -0100 1110 0111 0111:000:XNZVC:-----:00: RTR +0100 1110 0111 0111:000:XNZVC:-----:-R:00: RTR - 1 0 12 -0100 1110 0111 1010:100:?????:?????:10: MOVEC2 #1 +0100 1110 0111 1010:100:-----:-----:T-:10: MOVEC2 #1 - 6 0 6 -0100 1110 0111 1011:100:?????:?????:10: MOVE2C #1 +0100 1110 0111 1011:100:-----:-----:T-:10: MOVE2C #1 - 6 0 6 -0100 1110 10ss sSSS:000://///://///:80: JSR.L s[!Dreg,Areg,Aipi,Apdi,Immd] +0100 1110 10ss sSSS:000://///://///:-J:80: JSR.L s[!Dreg,Areg,Aipi,Apdi,Immd] - 0 0 4 jea -0100 rrr1 00ss sSSS:200:?????:?????:11: CHK.L s[!Areg],Dr -0100 rrr1 10ss sSSS:000:?????:?????:11: CHK.W s[!Areg],Dr +0100 rrr1 00ss sSSS:200:-N???:-----:T-:11: CHK.L s[!Areg],Dr +0100 rrr1 10ss sSSS:000:-N???:-----:T-:11: CHK.W s[!Areg],Dr -0100 1110 11ss sSSS:000://///://///:80: JMP.L s[!Dreg,Areg,Aipi,Apdi,Immd] +0100 1110 11ss sSSS:000://///://///:-J:80: JMP.L s[!Dreg,Areg,Aipi,Apdi,Immd] - 4 0 4 jea -0100 rrr1 11ss sSSS:000:-----:-----:02: LEA.L s[!Dreg,Areg,Aipi,Apdi,Immd],Ar +0100 rrr1 11ss sSSS:000:-----:-----:--:02: LEA.L s[!Dreg,Areg,Aipi,Apdi,Immd],Ar - 2 0 2 cea -0101 jjj0 01dd dDDD:000:-----:-----:13: ADDA.W #j,d[Areg] +% This variant of ADDQ is word and long sized only +0101 jjj0 01dd dDDD:000:-----:-----:--:13: ADDA.W #j,d[Areg] - 2 0 2 -0101 jjj0 10dd dDDD:000:-----:-----:13: ADDA.L #j,d[Areg] +0101 jjj0 10dd dDDD:000:-----:-----:--:13: ADDA.L #j,d[Areg] - 2 0 2 -0101 jjj0 zzdd dDDD:000:XNZVC:-----:13: ADD.z #j,d[Dreg] +0101 jjj0 zzdd dDDD:000:XNZVC:-----:--:13: ADD.z #j,d[Dreg] - 2 0 2 -0101 jjj0 zzdd dDDD:000:XNZVC:-----:13: ADD.z #j,d[!Areg,Dreg] +0101 jjj0 zzdd dDDD:000:XNZVC:-----:--:13: ADD.z #j,d[!Areg,Dreg] - 0 1 3 fea -0101 jjj1 01dd dDDD:000:-----:-----:13: SUBA.W #j,d[Areg] + +% This variant of SUBQ is word and long sized only +0101 jjj1 01dd dDDD:000:-----:-----:--:13: SUBA.W #j,d[Areg] - 2 0 2 -0101 jjj1 10dd dDDD:000:-----:-----:13: SUBA.L #j,d[Areg] +0101 jjj1 10dd dDDD:000:-----:-----:--:13: SUBA.L #j,d[Areg] - 2 0 2 -0101 jjj1 zzdd dDDD:000:XNZVC:-----:13: SUB.z #j,d[Dreg] +0101 jjj1 zzdd dDDD:000:XNZVC:-----:--:13: SUB.z #j,d[Dreg] - 2 0 2 -0101 jjj1 zzdd dDDD:000:XNZVC:-----:13: SUB.z #j,d[!Areg,Dreg] +0101 jjj1 zzdd dDDD:000:XNZVC:-----:--:13: SUB.z #j,d[!Areg,Dreg] - 0 1 3 fea -0101 cccc 1100 1rrr:000:-----:-++++:31: DBcc.W Dr,#1 +0101 cccc 1100 1rrr:000:-----:-++++:-B:31: DBcc.W Dr,#1 - -1 0 0 -0101 cccc 11dd dDDD:000:-----:-++++:20: Scc.B d[Dreg] +0101 cccc 11dd dDDD:000:-----:-++++:--:20: Scc.B d[Dreg] - 0 0 2 -0101 cccc 11dd dDDD:000:-----:-++++:20: Scc.B d[!Areg,Dreg] +0101 cccc 11dd dDDD:000:-----:-++++:--:20: Scc.B d[!Areg,Dreg] - 0 0 2 cea -0101 cccc 1111 1010:200:?????:?????:10: TRAPcc #1 -0101 cccc 1111 1011:200:?????:?????:10: TRAPcc #2 -0101 cccc 1111 1100:200:?????:?????:00: TRAPcc +0101 cccc 1111 1010:200:-----:-????:T-:10: TRAPcc #1 +0101 cccc 1111 1011:200:-----:-????:T-:10: TRAPcc #2 +0101 cccc 1111 1100:200:-----:-????:T-:00: TRAPcc % Bxx.L is 68020 only, but setting the CPU level to 2 would give illegal % instruction exceptions when compiling a 68000 only emulation, which isn't % what we want either. -0110 0001 0000 0000:000://///://///:40: BSR.W #1 +0110 0001 0000 0000:000://///://///:-B:40: BSR.W #1 - 2 0 6 -0110 0001 IIII IIII:000://///://///:40: BSR.B #i +0110 0001 IIII IIII:000://///://///:-B:40: BSR.B #i - 2 0 6 -0110 0001 1111 1111:000://///://///:40: BSR.L #2 +0110 0001 1111 1111:000://///://///:-B:40: BSR.L #2 - 2 0 6 -0110 CCCC 0000 0000:000:-----:-++++:40: Bcc.W #1 +0110 CCCC 0000 0000:000:-----:-++++:-B:40: Bcc.W #1 - -1 0 0 -0110 CCCC IIII IIII:000:-----:-++++:40: Bcc.B #i +0110 CCCC IIII IIII:000:-----:-++++:-B:40: Bcc.B #i - -1 0 0 -0110 CCCC 1111 1111:000:-----:-++++:40: Bcc.L #2 +0110 CCCC 1111 1111:000:-----:-++++:-B:40: Bcc.L #2 - -1 0 0 -0111 rrr0 iiii iiii:000:-NZ00:-----:12: MOVE.L #i,Dr +0111 rrr0 iiii iiii:000:-NZ00:-----:--:12: MOVE.L #i,Dr -1000 rrr0 zzss sSSS:000:-NZ00:-----:13: OR.z s[Dreg],Dr +1000 rrr0 zzss sSSS:000:-NZ00:-----:--:13: OR.z s[Dreg],Dr - 2 0 2 -1000 rrr0 zzss sSSS:000:-NZ00:-----:13: OR.z s[!Areg,Dreg],Dr +1000 rrr0 zzss sSSS:000:-NZ00:-----:--:13: OR.z s[!Areg,Dreg],Dr - 0 0 2 fea -1000 rrr0 11ss sSSS:000:?????:?????:13: DIVU.W s[Dreg],Dr +1000 rrr0 11ss sSSS:000:-NZV0:-----:T-:13: DIVU.W s[Dreg],Dr - 2 0 20 -1000 rrr0 11ss sSSS:000:?????:?????:13: DIVU.W s[!Areg,Dreg],Dr +1000 rrr0 11ss sSSS:000:-NZV0:-----:T-:13: DIVU.W s[!Areg,Dreg],Dr - 0 0 20 fea -1000 rrr1 00dd dDDD:000:XxZxC:X-Z--:13: SBCD.B d[Dreg],Dr +1000 rrr1 00dd dDDD:000:X?Z?C:X-Z--:--:13: SBCD.B d[Dreg],Dr - 0 0 4 -1000 rrr1 00dd dDDD:000:XxZxC:X-Z--:13: SBCD.B d[Areg-Apdi],Arp +1000 rrr1 00dd dDDD:000:X?Z?C:X-Z--:--:13: SBCD.B d[Areg-Apdi],Arp - 2 1 13 -1000 rrr1 zzdd dDDD:000:-NZ00:-----:13: OR.z Dr,d[!Areg,Dreg] +1000 rrr1 zzdd dDDD:000:-NZ00:-----:--:13: OR.z Dr,d[!Areg,Dreg] - 0 1 3 fea -1000 rrr1 01dd dDDD:200:?????:?????:12: PACK d[Dreg],Dr +1000 rrr1 01dd dDDD:200:-----:-----:--:12: PACK d[Dreg],Dr - 6 0 6 -1000 rrr1 01dd dDDD:200:?????:?????:12: PACK d[Areg-Apdi],Arp +1000 rrr1 01dd dDDD:200:-----:-----:--:12: PACK d[Areg-Apdi],Arp - 2 1 11 -1000 rrr1 10dd dDDD:200:?????:?????:12: UNPK d[Dreg],Dr +1000 rrr1 10dd dDDD:200:-----:-----:--:12: UNPK d[Dreg],Dr - 8 0 8 -1000 rrr1 10dd dDDD:200:?????:?????:12: UNPK d[Areg-Apdi],Arp +1000 rrr1 10dd dDDD:200:-----:-----:--:12: UNPK d[Areg-Apdi],Arp - 2 1 11 -1000 rrr1 11ss sSSS:000:?????:?????:13: DIVS.W s[Dreg],Dr +1000 rrr1 11ss sSSS:000:-NZV0:-----:T-:13: DIVS.W s[Dreg],Dr - 2 0 20 -1000 rrr1 11ss sSSS:000:?????:?????:13: DIVS.W s[!Areg,Dreg],Dr +1000 rrr1 11ss sSSS:000:-NZV0:-----:T-:13: DIVS.W s[!Areg,Dreg],Dr - 0 0 20 fea -1001 rrr0 zzss sSSS:000:XNZVC:-----:13: SUB.z s[Areg,Dreg],Dr +1001 rrr0 zzss sSSS:000:XNZVC:-----:--:13: SUB.z s[Areg,Dreg],Dr - 2 0 2 -1001 rrr0 zzss sSSS:000:XNZVC:-----:13: SUB.z s[!Areg,Dreg],Dr +1001 rrr0 zzss sSSS:000:XNZVC:-----:--:13: SUB.z s[!Areg,Dreg],Dr - 0 0 2 fea -1001 rrr0 11ss sSSS:000:-----:-----:13: SUBA.W s[Areg,Dreg],Ar +1001 rrr0 11ss sSSS:000:-----:-----:--:13: SUBA.W s[Areg,Dreg],Ar - 4 0 4 -1001 rrr0 11ss sSSS:000:-----:-----:13: SUBA.W s[!Areg,Dreg],Ar +1001 rrr0 11ss sSSS:000:-----:-----:--:13: SUBA.W s[!Areg,Dreg],Ar - 0 0 4 fea -1001 rrr1 zzdd dDDD:000:XNZVC:X-Z--:13: SUBX.z d[Dreg],Dr +1001 rrr1 zzdd dDDD:000:XNZVC:X-Z--:--:13: SUBX.z d[Dreg],Dr - 2 0 2 -1001 rrr1 zzdd dDDD:000:XNZVC:X-Z--:13: SUBX.z d[Areg-Apdi],Arp +1001 rrr1 zzdd dDDD:000:XNZVC:X-Z--:--:13: SUBX.z d[Areg-Apdi],Arp - 2 1 9 -1001 rrr1 zzdd dDDD:000:XNZVC:-----:13: SUB.z Dr,d[!Areg,Dreg] +1001 rrr1 zzdd dDDD:000:XNZVC:-----:--:13: SUB.z Dr,d[!Areg,Dreg] - 0 1 3 fea -1001 rrr1 11ss sSSS:000:-----:-----:13: SUBA.L s[Areg,Dreg],Ar +1001 rrr1 11ss sSSS:000:-----:-----:--:13: SUBA.L s[Areg,Dreg],Ar - 2 0 2 -1001 rrr1 11ss sSSS:000:-----:-----:13: SUBA.L s[!Areg,Dreg],Ar +1001 rrr1 11ss sSSS:000:-----:-----:--:13: SUBA.L s[!Areg,Dreg],Ar - 0 0 2 fea -1011 rrr0 zzss sSSS:000:-NZVC:-----:11: CMP.z s[Areg,Dreg],Dr +1011 rrr0 zzss sSSS:000:-NZVC:-----:--:11: CMP.z s[Areg,Dreg],Dr - 2 0 2 -1011 rrr0 zzss sSSS:000:-NZVC:-----:11: CMP.z s[!Areg,Dreg],Dr +1011 rrr0 zzss sSSS:000:-NZVC:-----:--:11: CMP.z s[!Areg,Dreg],Dr - 0 0 2 fea -1011 rrr0 11ss sSSS:000:-NZVC:-----:11: CMPA.W s[Areg,Dreg],Ar +1011 rrr0 11ss sSSS:000:-NZVC:-----:--:11: CMPA.W s[Areg,Dreg],Ar - 4 0 4 -1011 rrr0 11ss sSSS:000:-NZVC:-----:11: CMPA.W s[!Areg,Dreg],Ar +1011 rrr0 11ss sSSS:000:-NZVC:-----:--:11: CMPA.W s[!Areg,Dreg],Ar - 0 0 4 fea -1011 rrr1 11ss sSSS:000:-NZVC:-----:11: CMPA.L s[Areg,Dreg],Ar +1011 rrr1 11ss sSSS:000:-NZVC:-----:--:11: CMPA.L s[Areg,Dreg],Ar - 4 0 4 -1011 rrr1 11ss sSSS:000:-NZVC:-----:11: CMPA.L s[!Areg,Dreg],Ar +1011 rrr1 11ss sSSS:000:-NZVC:-----:--:11: CMPA.L s[!Areg,Dreg],Ar - 0 0 4 fea -1011 rrr1 zzdd dDDD:000:-NZVC:-----:11: CMPM.z d[Areg-Aipi],ArP +1011 rrr1 zzdd dDDD:000:-NZVC:-----:--:11: CMPM.z d[Areg-Aipi],ArP - 0 0 8 -1011 rrr1 zzdd dDDD:000:-NZ00:-----:13: EOR.z Dr,d[Dreg] +1011 rrr1 zzdd dDDD:000:-NZ00:-----:--:13: EOR.z Dr,d[Dreg] - 2 0 2 -1011 rrr1 zzdd dDDD:000:-NZ00:-----:13: EOR.z Dr,d[!Areg,Dreg] +1011 rrr1 zzdd dDDD:000:-NZ00:-----:--:13: EOR.z Dr,d[!Areg,Dreg] - 0 1 3 fea -1100 rrr0 zzss sSSS:000:-NZ00:-----:13: AND.z s[Dreg],Dr +1100 rrr0 zzss sSSS:000:-NZ00:-----:--:13: AND.z s[Dreg],Dr - 2 0 2 fea -1100 rrr0 zzss sSSS:000:-NZ00:-----:13: AND.z s[!Areg,Dreg],Dr +1100 rrr0 zzss sSSS:000:-NZ00:-----:--:13: AND.z s[!Areg,Dreg],Dr - 0 1 3 fea -1100 rrr0 11ss sSSS:000:-NZ00:-----:13: MULU.W s[!Areg],Dr +1100 rrr0 11ss sSSS:000:-NZ00:-----:--:13: MULU.W s[!Areg],Dr - 2 0 12 fea -1100 rrr1 00dd dDDD:000:XxZxC:X-Z--:13: ABCD.B d[Dreg],Dr +1100 rrr1 00dd dDDD:000:X?Z?C:X-Z--:--:13: ABCD.B d[Dreg],Dr - 0 0 4 -1100 rrr1 00dd dDDD:000:XxZxC:X-Z--:13: ABCD.B d[Areg-Apdi],Arp +1100 rrr1 00dd dDDD:000:X?Z?C:X-Z--:--:13: ABCD.B d[Areg-Apdi],Arp - 2 1 13 -1100 rrr1 zzdd dDDD:000:-NZ00:-----:13: AND.z Dr,d[!Areg,Dreg] +1100 rrr1 zzdd dDDD:000:-NZ00:-----:--:13: AND.z Dr,d[!Areg,Dreg] - 0 1 3 fea -1100 rrr1 01dd dDDD:000:-----:-----:33: EXG.L Dr,d[Dreg] +1100 rrr1 01dd dDDD:000:-----:-----:--:33: EXG.L Dr,d[Dreg] - 4 0 4 -1100 rrr1 01dd dDDD:000:-----:-----:33: EXG.L Ar,d[Areg] +1100 rrr1 01dd dDDD:000:-----:-----:--:33: EXG.L Ar,d[Areg] - 4 0 4 -1100 rrr1 10dd dDDD:000:-----:-----:33: EXG.L Dr,d[Areg] +1100 rrr1 10dd dDDD:000:-----:-----:--:33: EXG.L Dr,d[Areg] - 4 0 4 -1100 rrr1 11ss sSSS:000:-NZ00:-----:13: MULS.W s[!Areg],Dr +1100 rrr1 11ss sSSS:000:-NZ00:-----:--:13: MULS.W s[!Areg],Dr - 2 0 12 fea -1101 rrr0 zzss sSSS:000:XNZVC:-----:13: ADD.z s[Areg,Dreg],Dr +1101 rrr0 zzss sSSS:000:XNZVC:-----:--:13: ADD.z s[Areg,Dreg],Dr - 2 0 2 -1101 rrr0 zzss sSSS:000:XNZVC:-----:13: ADD.z s[!Areg,Dreg],Dr +1101 rrr0 zzss sSSS:000:XNZVC:-----:--:13: ADD.z s[!Areg,Dreg],Dr - 0 0 2 fea -1101 rrr0 11ss sSSS:000:-----:-----:13: ADDA.W s[Areg,Dreg],Ar +1101 rrr0 11ss sSSS:000:-----:-----:--:13: ADDA.W s[Areg,Dreg],Ar - 0 0 4 -1101 rrr0 11ss sSSS:000:-----:-----:13: ADDA.W s[!Areg,Dreg],Ar +1101 rrr0 11ss sSSS:000:-----:-----:--:13: ADDA.W s[!Areg,Dreg],Ar - 4 0 4 fea -1101 rrr1 zzdd dDDD:000:XNZVC:X-Z--:13: ADDX.z d[Dreg],Dr +1101 rrr1 zzdd dDDD:000:XNZVC:X-Z--:--:13: ADDX.z d[Dreg],Dr - 2 0 2 -1101 rrr1 zzdd dDDD:000:XNZVC:X-Z--:13: ADDX.z d[Areg-Apdi],Arp +1101 rrr1 zzdd dDDD:000:XNZVC:X-Z--:--:13: ADDX.z d[Areg-Apdi],Arp - 2 1 9 -1101 rrr1 zzdd dDDD:000:XNZVC:-----:13: ADD.z Dr,d[!Areg,Dreg] +1101 rrr1 zzdd dDDD:000:XNZVC:-----:--:13: ADD.z Dr,d[!Areg,Dreg] - 0 1 3 fea -1101 rrr1 11ss sSSS:000:-----:-----:13: ADDA.L s[Areg,Dreg],Ar +1101 rrr1 11ss sSSS:000:-----:-----:--:13: ADDA.L s[Areg,Dreg],Ar - 2 0 2 -1101 rrr1 11ss sSSS:000:-----:-----:13: ADDA.L s[!Areg,Dreg],Ar +1101 rrr1 11ss sSSS:000:-----:-----:--:13: ADDA.L s[!Areg,Dreg],Ar - 0 0 2 fea -1110 jjjf zz00 0RRR:000:XNZVC:-----:13: ASf.z #j,DR +1110 jjjf zz00 0RRR:000:XNZVC:-----:--:13: ASf.z #j,DR - 2 0 6 -1110 jjjf zz00 1RRR:000:XNZ0C:-----:13: LSf.z #j,DR +1110 jjjf zz00 1RRR:000:XNZ0C:-----:--:13: LSf.z #j,DR - 4 0 4 -1110 jjjf zz01 0RRR:000:XNZ0C:X----:13: ROXf.z #j,DR +1110 jjjf zz01 0RRR:000:XNZ0C:X----:--:13: ROXf.z #j,DR - 10 0 12 -1110 jjjf zz01 1RRR:000:-NZ0C:-----:13: ROf.z #j,DR +1110 jjjf zz01 1RRR:000:-NZ0C:-----:--:13: ROf.z #j,DR - 4 0 6 -1110 rrrf zz10 0RRR:000:XNZVC:X----:13: ASf.z Dr,DR +1110 rrrf zz10 0RRR:000:XNZVC:X----:--:13: ASf.z Dr,DR - 4 0 6 -1110 rrrf zz10 1RRR:000:XNZ0C:X----:13: LSf.z Dr,DR +1110 rrrf zz10 1RRR:000:XNZ0C:X----:--:13: LSf.z Dr,DR - 6 0 6 -1110 rrrf zz11 0RRR:000:XNZ0C:X----:13: ROXf.z Dr,DR +1110 rrrf zz11 0RRR:000:XNZ0C:X----:--:13: ROXf.z Dr,DR - 10 0 12 -1110 rrrf zz11 1RRR:000:-NZ0C:-----:13: ROf.z Dr,DR +1110 rrrf zz11 1RRR:000:-NZ0C:-----:--:13: ROf.z Dr,DR - 6 0 8 -1110 000f 11dd dDDD:000:XNZVC:-----:13: ASfW.W d[!Dreg,Areg] +1110 000f 11dd dDDD:000:XNZVC:-----:--:13: ASfW.W d[!Dreg,Areg] - 0 0 4 fea -1110 001f 11dd dDDD:000:XNZ0C:-----:13: LSfW.W d[!Dreg,Areg] +1110 001f 11dd dDDD:000:XNZ0C:-----:--:13: LSfW.W d[!Dreg,Areg] - 0 0 4 fea -1110 010f 11dd dDDD:000:XNZ0C:X----:13: ROXfW.W d[!Dreg,Areg] +1110 010f 11dd dDDD:000:XNZ0C:X----:--:13: ROXfW.W d[!Dreg,Areg] - 0 0 4 fea -1110 011f 11dd dDDD:000:-NZ0C:-----:13: ROfW.W d[!Dreg,Areg] +1110 011f 11dd dDDD:000:-NZ0C:-----:--:13: ROfW.W d[!Dreg,Areg] - 0 0 6 fea -1110 1000 11ss sSSS:200:?????:?????:11: BFTST #1,s[!Areg,Apdi,Aipi,Immd] -1110 1001 11ss sSSS:200:?????:?????:11: BFEXTU #1,s[!Areg,Apdi,Aipi,Immd] -1110 1010 11ss sSSS:200:?????:?????:13: BFCHG #1,s[!Areg,Apdi,Aipi,Immd,PC8r,PC16] -1110 1011 11ss sSSS:200:?????:?????:11: BFEXTS #1,s[!Areg,Apdi,Aipi,Immd] -1110 1100 11ss sSSS:200:?????:?????:13: BFCLR #1,s[!Areg,Apdi,Aipi,Immd,PC8r,PC16] -1110 1101 11ss sSSS:200:?????:?????:11: BFFFO #1,s[!Areg,Apdi,Aipi,Immd] -1110 1110 11ss sSSS:200:?????:?????:13: BFSET #1,s[!Areg,Apdi,Aipi,Immd,PC8r,PC16] -1110 1111 11ss sSSS:200:?????:?????:13: BFINS #1,s[!Areg,Apdi,Aipi,Immd,PC8r,PC16] +1110 1000 11ss sSSS:200:-NZ00:-----:--:11: BFTST #1,s[!Areg,Apdi,Aipi,Immd] +1110 1001 11ss sSSS:200:-NZ00:-----:--:11: BFEXTU #1,s[!Areg,Apdi,Aipi,Immd] +1110 1010 11ss sSSS:200:-NZ00:-----:--:13: BFCHG #1,s[!Areg,Apdi,Aipi,Immd,PC8r,PC16] +1110 1011 11ss sSSS:200:-NZ00:-----:--:11: BFEXTS #1,s[!Areg,Apdi,Aipi,Immd] +1110 1100 11ss sSSS:200:-NZ00:-----:--:13: BFCLR #1,s[!Areg,Apdi,Aipi,Immd,PC8r,PC16] +1110 1101 11ss sSSS:200:-NZ00:-----:--:11: BFFFO #1,s[!Areg,Apdi,Aipi,Immd] +1110 1110 11ss sSSS:200:-NZ00:-----:--:13: BFSET #1,s[!Areg,Apdi,Aipi,Immd,PC8r,PC16] +1110 1111 11ss sSSS:200:-NZ00:-----:--:13: BFINS #1,s[!Areg,Apdi,Aipi,Immd,PC8r,PC16] % floating point co processor -1111 0010 00ss sSSS:200:?????:?????:11: FPP #1,s -1111 0010 01ss sSSS:200:?????:?????:11: FDBcc #1,s[Areg-Dreg] -1111 0010 01ss sSSS:200:?????:?????:11: FScc #1,s[!Areg,Immd,PC8r,PC16] -1111 0010 0111 1010:200:?????:?????:10: FTRAPcc #1 -1111 0010 0111 1011:200:?????:?????:10: FTRAPcc #2 -1111 0010 0111 1100:200:?????:?????:00: FTRAPcc -1111 0010 10KK KKKK:200:?????:?????:11: FBcc #K,#1 -1111 0010 11KK KKKK:200:?????:?????:11: FBcc #K,#2 -1111 0011 00ss sSSS:202:?????:?????:20: FSAVE s[!Dreg,Areg,Aipi,Immd,PC8r,PC16] -1111 0011 01ss sSSS:202:?????:?????:10: FRESTORE s[!Dreg,Areg,Apdi,Immd] +1111 0010 00ss sSSS:200:-----:-----:--:11: FPP #1,s +1111 0010 01ss sSSS:200:-----:-----:-B:11: FDBcc #1,s[Areg-Dreg] +1111 0010 01ss sSSS:200:-----:-----:--:11: FScc #1,s[!Areg,Immd,PC8r,PC16] +1111 0010 0111 1010:200:-----:-----:T-:10: FTRAPcc #1 +1111 0010 0111 1011:200:-----:-----:T-:10: FTRAPcc #2 +1111 0010 0111 1100:200:-----:-----:T-:00: FTRAPcc +1111 0010 10KK KKKK:200:-----:-----:-B:11: FBcc #K,#1 +1111 0010 11KK KKKK:200:-----:-----:-B:11: FBcc #K,#2 +1111 0011 00ss sSSS:202:-----:-----:--:20: FSAVE s[!Dreg,Areg,Aipi,Immd,PC8r,PC16] +1111 0011 01ss sSSS:202:-----:-----:--:10: FRESTORE s[!Dreg,Areg,Apdi,Immd] % 68030 MMU (allowed addressing modes not checked!) -1111 0000 00ss sSSS:342:?????:?????:11: MMUOP030 s[Dreg,Areg,Apdi,Aipi,Aind,Ad16,Ad8r,absl,absw],#1 +1111 0000 00ss sSSS:342:-----:-----:T-:11: MMUOP030 s[Dreg,Areg,Apdi,Aipi,Aind,Ad16,Ad8r,absl,absw],#1 % 68040/68060 instructions -1111 0100 pp00 1rrr:402:-----:-----:02: CINVL #p,Ar -1111 0100 pp01 0rrr:402:-----:-----:02: CINVP #p,Ar -1111 0100 pp01 1rrr:402:-----:-----:00: CINVA #p -1111 0100 pp10 1rrr:402:-----:-----:02: CPUSHL #p,Ar -1111 0100 pp11 0rrr:402:-----:-----:02: CPUSHP #p,Ar -1111 0100 pp11 1rrr:402:-----:-----:00: CPUSHA #p -1111 0101 0000 0rrr:402:-----:-----:00: PFLUSHN Ara -1111 0101 0000 1rrr:402:-----:-----:00: PFLUSH Ara -1111 0101 0001 0rrr:402:-----:-----:00: PFLUSHAN Ara -1111 0101 0001 1rrr:402:-----:-----:00: PFLUSHA Ara +1111 0100 pp00 1rrr:402:-----:-----:T-:02: CINVL #p,Ar +1111 0100 pp01 0rrr:402:-----:-----:T-:02: CINVP #p,Ar +1111 0100 pp01 1rrr:402:-----:-----:T-:00: CINVA #p +1111 0100 pp10 1rrr:402:-----:-----:T-:02: CPUSHL #p,Ar +1111 0100 pp11 0rrr:402:-----:-----:T-:02: CPUSHP #p,Ar +1111 0100 pp11 1rrr:402:-----:-----:T-:00: CPUSHA #p +1111 0101 0000 0rrr:402:-----:-----:T-:00: PFLUSHN Ara +1111 0101 0000 1rrr:402:-----:-----:T-:00: PFLUSH Ara +1111 0101 0001 0rrr:402:-----:-----:T-:00: PFLUSHAN Ara +1111 0101 0001 1rrr:402:-----:-----:T-:00: PFLUSHA Ara % 68040 only -1111 0101 0100 1rrr:452:-----:-----:00: PTESTW Ara -1111 0101 0110 1rrr:452:-----:-----:00: PTESTR Ara +1111 0101 0100 1rrr:452:-----:-----:T-:00: PTESTW Ara +1111 0101 0110 1rrr:452:-----:-----:T-:00: PTESTR Ara % destination register number is encoded in the following word -1111 0110 0010 0rrr:400:-----:-----:12: MOVE16 ArP,AxP -1111 0110 00ss sSSS:400:-----:-----:12: MOVE16 s[Dreg-Aipi],L -1111 0110 00dd dDDD:400:-----:-----:12: MOVE16 L,d[Areg-Aipi] -1111 0110 00ss sSSS:400:-----:-----:12: MOVE16 s[Aind],L -1111 0110 00dd dDDD:400:-----:-----:12: MOVE16 L,d[Aipi-Aind] +1111 0110 0010 0rrr:400:-----:-----:--:12: MOVE16 ArP,AxP +1111 0110 00ss sSSS:400:-----:-----:--:12: MOVE16 s[Dreg-Aipi],Al +1111 0110 00dd dDDD:400:-----:-----:--:12: MOVE16 Al,d[Areg-Aipi] +1111 0110 00ss sSSS:400:-----:-----:--:12: MOVE16 s[Aind],Al +1111 0110 00dd dDDD:400:-----:-----:--:12: MOVE16 Al,d[Aipi-Aind] % 68060 -1111 1000 0000 0000:500:?????:?????:10: LPSTOP #1 -1111 0101 1000 1rrr:502:-----:-----:00: PLPAW Ara -1111 0101 1100 1rrr:502:-----:-----:00: PLPAR Ara +1111 1000 0000 0000:500:XNZVC:-----:T-:10: LPSTOP #1 +1111 0101 1000 1rrr:502:-----:-----:T-:00: PLPAW Ara +1111 0101 1100 1rrr:502:-----:-----:T-:00: PLPAR Ara % "Debug Pipe Control Mode Commands" -0100 1010 1100 1000:502:?????:?????:00: HALT -0100 1010 1100 1100:500:?????:?????:00: PULSE +0100 1010 1100 1000:502:-----:-----:--:00: HALT +0100 1010 1100 1100:500:-----:-----:--:00: PULSE -- 2.47.3