]> git.unchartedbackwaters.co.uk Git - francis/winuae.git/commitdiff
Aranym JIT merge.
authorToni Wilen <twilen@winuae.net>
Mon, 27 Jul 2020 16:56:31 +0000 (19:56 +0300)
committerToni Wilen <twilen@winuae.net>
Mon, 27 Jul 2020 16:56:31 +0000 (19:56 +0300)
27 files changed:
build68k.cpp
fpp.cpp
gencpu.cpp
include/debug.h
include/newcpu.h
include/readcpu.h
include/sysdeps.h
include/uae/memory.h [new file with mode: 0644]
jit/codegen_x86.cpp
jit/codegen_x86.h
jit/compemu.h
jit/compemu_fpp.cpp
jit/compemu_midfunc_x86.cpp
jit/compemu_midfunc_x86.h
jit/compemu_support.cpp
jit/gencomp.cpp
jit/memory-uae.h [new file with mode: 0644]
main.cpp
memory.cpp
newcpu.cpp
newcpu_common.cpp
od-win32/machdep/m68k.cpp
od-win32/machdep/m68k.h
od-win32/machdep/maccess.h
od-win32/sysconfig.h
readcpu.cpp
table68k

index c83e99f69d4201352c24e06dd0b46fa739c96833..82ad4fb31f9259e90892426e7dab92d42573c8b0 100644 (file)
@@ -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 3b9446e2bfd208e23fc52b1074b2caab96e9f309..3ac7286fe32fd290c88609d9c222502980ed166c 100644 (file)
--- 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);
        }
 }
 
index 65e63b2fa072a7633dda6f0c5a726d7458754d0f..b4f3fe510129f54035c67a5ddf903f52a77e9b24 100644 (file)
@@ -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);
index 92515ce3e2c561fde5e1571fd8a2319e0a636fa3..284bae69aaf0f7f6a935240b5980ba8ca908a4f4 100644 (file)
 
 #include "uae/types.h"
 
+#ifndef D
+#define D
+#endif
+#ifndef bug
+#define bug write_log
+#endif
+
 #ifdef DEBUGGER
 
 #define        MAX_HIST 500
index 3c818a9e8a2e25111aa7317a5a7c7d8b743ebe32..355fb132c9e94471fb8222a8e4f6d7c7acedace3 100644 (file)
@@ -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)
index da7798704e36ea3387a7df0b4730b5094c3597bd..5a13bcc3bc02f89804e9d3aaf61b5833c02fae11 100644 (file)
@@ -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);
 
index 94d4c31fe0af5178c5814b3ba03c62629178812d..835e6bbdf3aa8480f8f3aad86ec28ef73d664256 100644 (file)
@@ -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 (file)
index 0000000..1270eae
--- /dev/null
@@ -0,0 +1,2 @@
+#include "options.h"
+#include "../memory.h"
index 8bd53e85c0ef093cdca7fa1fe1f53778508e3c16..1e1786296c02d46b607762c50f90408a2e36e6ae 100644 (file)
@@ -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
index b37b48f8781274c5b365acbea2a6bc1f721b565b..0eaef50afcc5d669b6b10a3f43ace6b8398e0818 100644 (file)
@@ -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)                              ))
index 5dd6d55a8d1e17bc2e745b883c9b1eb7747b75f9..70f76dcd957a450023a4f6ba8eb2a338c41a9568 100644 (file)
@@ -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
index 3a14920eff9eb8c26a95e4877c16bb9ccfc6de30..ac39bc71240f3b2ab8086e7d3049cceb5685a145 100644 (file)
 /*
-  * 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 <cmath>
+#include <cstdio>
+#include <cassert>
+
+#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 <EA> */
+#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)&regs.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)&regs.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)&regs.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 <EA> */
-                       write_log (_T ("JIT FMOVE FPx,<EA> 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.
-   >=<U
-   0000    0x00: 0                        ---   Never jump
-   0101    0x01: Z                        ---   jump if zero (x86: 4)
-   1000    0x02: !(NotANumber || Z || N)  --- Neither Z nor N set (x86: 7)
-   1101    0x03: Z || !(NotANumber || N); --- Z or !N (x86: 4 and 3)
-   0010    0x04: N && !(NotANumber || Z); --- N and !Z (x86: hard!)
-   0111    0x05: Z || (N && !NotANumber); --- Z or N (x86: 6)
-   1010    0x06: !(NotANumber || Z);      --- not Z (x86: 5)
-   1110    0x07: !NotANumber;             --- not NaN (x86: 11, not parity)
-   0001    0x08: NotANumber;              --- NaN (x86: 10)
-   0101    0x09: NotANumber || Z;         --- Z (x86: 4)
-   1001    0x0a: NotANumber || !(N || Z); --- NaN or neither N nor Z (x86: 10 and 7)
-   1101    0x0b: NotANumber || Z || !N;   --- Z or !N (x86: 4 and 3)
-   0011    0x0c: NotANumber || (N && !Z); --- N (x86: 2)
-   0111    0x0d: NotANumber || Z || N;    --- Z or N (x86: 6)
-   1010    0x0e: !Z;                      --- not Z (x86: 5)
-   1111    0x0f: 1;                       --- always
-
-   This is not how the 68k handles things, though --- it sets Z to 0 and N
-   to the NaN's sign.... ('o' and 'i' denote differences from the above
-   table)
-
-   >=<U
-   0000    0x00: 0                        ---   Never jump
-   010o    0x01: Z                        ---   jump if zero (x86: 4, not 10)
-   1000    0x02: !(NotANumber || Z || N)  --- Neither Z nor N set (x86: 7)
-   110o    0x03: Z || !(NotANumber || N); --- Z or !N (x86: 3)
-   0010    0x04: N && !(NotANumber || Z); --- N and !Z (x86: 2, not 10)
-   011o    0x05: Z || (N && !NotANumber); --- Z or N (x86: 6, not 10)
-   1010    0x06: !(NotANumber || Z);      --- not Z (x86: 5)
-   1110    0x07: !NotANumber;             --- not NaN (x86: 11, not parity)
-   0001    0x08: NotANumber;              --- NaN (x86: 10)
-   0101    0x09: NotANumber || Z;         --- Z (x86: 4)
-   1001    0x0a: NotANumber || !(N || Z); --- NaN or neither N nor Z (x86: 10 and 7)
-   1101    0x0b: NotANumber || Z || !N;   --- Z or !N (x86: 4 and 3)
-   0011    0x0c: NotANumber || (N && !Z); --- N (x86: 2)
-   0111    0x0d: NotANumber || Z || N;    --- Z or N (x86: 6)
-   101i    0x0e: !Z;                      --- not Z (x86: 5 and 10)
-   1111    0x0f: 1;                       --- always
-
-   Of course, this *still* doesn't mean that the x86 and 68k conditions are
-   equivalent --- the handling of infinities is different, for one thing.
-   On the 68k, +infinity minus +infinity is NotANumber (as it should be). On
-   the x86, it is +infinity, and some exception is raised (which I suspect
-   is promptly ignored) STUPID!
-   The more I learn about their CPUs, the more I detest Intel....
-
-   You can see this in action if you have "Benoit" (see Aminet) and
-   set the exponent to 16. Wait for a long time, and marvel at the extra black
-   areas outside the center one. That's where Benoit expects NaN, and the x86
-   gives +infinity. [Ooops --- that must have been some kind of bug in my code.
-   it no longer happens, and the resulting graphic looks much better, too]
-
-   x86 conditions
-   0011    : 2
-   1100    : 3
-   0101    : 4
-   1010    : 5
-   0111    : 6
-   1000    : 7
-   0001    : 10
-   1110    : 11
-   */
-void comp_fsave_opp (uae_u32 opcode)
-{
-       FAIL (1);
-       return;
-}
 
-void comp_frestore_opp (uae_u32 opcode)
+    /* Floating point conditions 
+       The "NotANumber" part could be problematic; Howver, 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.
+>=<U 
+0000    0x00: 0                        ---   Never jump
+0101    0x01: Z                        ---   jump if zero (x86: 4)
+1000    0x02: !(NotANumber || Z || N)  --- Neither Z nor N set (x86: 7)
+1101    0x03: Z || !(NotANumber || N); --- Z or !N (x86: 4 and 3)
+0010    0x04: N && !(NotANumber || Z); --- N and !Z (x86: hard!)
+0111    0x05: Z || (N && !NotANumber); --- Z or N (x86: 6)
+1010    0x06: !(NotANumber || Z);      --- not Z (x86: 5)
+1110    0x07: !NotANumber;             --- not NaN (x86: 11, not parity)
+0001    0x08: NotANumber;              --- NaN (x86: 10)
+0101    0x09: NotANumber || Z;         --- Z (x86: 4)
+1001    0x0a: NotANumber || !(N || Z); --- NaN or neither N nor Z (x86: 10 and 7)
+1101    0x0b: NotANumber || Z || !N;   --- Z or !N (x86: 4 and 3)
+0011    0x0c: NotANumber || (N && !Z); --- N (x86: 2)
+0111    0x0d: NotANumber || Z || N;    --- Z or N (x86: 6)
+1010    0x0e: !Z;                      --- not Z (x86: 5)
+1111    0x0f: 1;                       --- always
+
+This is not how the 68k handles things, though --- it sets Z to 0 and N
+to the NaN's sign.... ('o' and 'i' denote differences from the above
+table)
+
+>=<U 
+0000    0x00: 0                        ---   Never jump
+010o    0x01: Z                        ---   jump if zero (x86: 4, not 10)
+1000    0x02: !(NotANumber || Z || N)  --- Neither Z nor N set (x86: 7)
+110o    0x03: Z || !(NotANumber || N); --- Z or !N (x86: 3)
+0010    0x04: N && !(NotANumber || Z); --- N and !Z (x86: 2, not 10)
+011o    0x05: Z || (N && !NotANumber); --- Z or N (x86: 6, not 10)
+1010    0x06: !(NotANumber || Z);      --- not Z (x86: 5)
+1110    0x07: !NotANumber;             --- not NaN (x86: 11, not parity)
+0001    0x08: NotANumber;              --- NaN (x86: 10)
+0101    0x09: NotANumber || Z;         --- Z (x86: 4)
+1001    0x0a: NotANumber || !(N || Z); --- NaN or neither N nor Z (x86: 10 and 7)
+1101    0x0b: NotANumber || Z || !N;   --- Z or !N (x86: 4 and 3)
+0011    0x0c: NotANumber || (N && !Z); --- N (x86: 2)
+0111    0x0d: NotANumber || Z || N;    --- Z or N (x86: 6)
+101i    0x0e: !Z;                      --- not Z (x86: 5 and 10)
+1111    0x0f: 1;                       --- always
+
+Of course, this *still* doesn't mean that the x86 and 68k conditions are
+equivalent --- the handling of infinities is different, for one thing.
+On the 68k, +infinity minus +infinity is NotANumber (as it should be). On
+the x86, it is +infinity, and some exception is raised (which I suspect
+is promptly ignored) STUPID! 
+The more I learn about their CPUs, the more I detest Intel....
+
+You can see this in action if you have "Benoit" (see Aminet) and
+set the exponent to 16. Wait for a long time, and marvel at the extra black
+areas outside the center one. That's where Benoit expects NaN, and the x86
+gives +infinity. [Ooops --- that must have been some kind of bug in my code.
+it no longer happens, and the resulting graphic looks much better, too]
+
+x86 conditions
+0011    : 2
+1100    : 3
+0101    : 4
+1010    : 5
+0111    : 6
+1000    : 7
+0001    : 10
+1110    : 11
+    */
+
+#ifndef UAE
+void comp_fsave_opp(uae_u32 opcode)
 {
-       FAIL (1);
+       int incr = (opcode & 0x38) == 0x20 ? -1 : 1;
+       int i;
+       int ad;
+
+       if (jit_disable.fsave)
+       {
+               FAIL(1);
+               return;
+       }
+       FAIL(1);
        return;
+
+       if ((ad = get_fp_ad(opcode)) < 0)
+       {
+               FAIL(1);
+               return;
+       }
+
+       if (currprefs.fpu_model == 68040)
+       {
+               /* 4 byte 68040 IDLE frame.  */
+               if (incr < 0)
+               {
+                       ad -= 4;
+                       put_long(ad, 0x41000000);
+               } else
+               {
+                       put_long(ad, 0x41000000);
+                       ad += 4;
+               }
+       } else
+       {
+               if (incr < 0)
+               {
+                       ad -= 4;
+                       put_long(ad, 0x70000000);
+                       for (i = 0; i < 5; i++)
+                       {
+                               ad -= 4;
+                               put_long(ad, 0x00000000);
+                       }
+                       ad -= 4;
+                       put_long(ad, 0x1f180000);
+               } else
+               {
+                       put_long(ad, 0x1f180000);
+                       ad += 4;
+                       for (i = 0; i < 5; i++)
+                       {
+                               put_long(ad, 0x00000000);
+                               ad += 4;
+                       }
+                       put_long(ad, 0x70000000);
+                       ad += 4;
+               }
+       }
+       if ((opcode & 0x38) == 0x18)
+               m68k_areg(regs, opcode & 7) = ad;
+       if ((opcode & 0x38) == 0x20)
+               m68k_areg(regs, opcode & 7) = ad;
 }
 
-extern uae_u32 xhex_pi[], xhex_exp_1[], xhex_l2_e[], xhex_ln_2[], xhex_ln_10[];
-extern uae_u32 xhex_l10_2[], xhex_l10_e[], xhex_1e16[], xhex_1e32[], xhex_1e64[];
-extern uae_u32 xhex_1e128[], xhex_1e256[], xhex_1e512[], xhex_1e1024[];
-extern uae_u32 xhex_1e2048[], xhex_1e4096[];
-extern double fp_1e8;
-extern float  fp_1e1, fp_1e2, fp_1e4;
 
-void comp_fpp_opp (uae_u32 opcode, uae_u16 extra)
+void comp_frestore_opp(uae_u32 opcode)
 {
-       int reg;
-       int sreg, prec = 0;
-       int     dreg = (extra >> 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, <EA> */
-               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  <EA>, ControlReg */
-               if (!(opcode & 0x30)) { /* Dn or An */
-                       if (extra & 0x1000) { /* FPCR */
-                               mov_l_mr (uae_p32(&regs.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(&regs.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(&regs.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(&regs.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, <EA> */
-               if (!(opcode & 0x30)) { /* Dn or An */
-                       if (extra & 0x1000) { /* FPCR */
-                               mov_l_rm (opcode & 15, uae_p32(&regs.fpcr)); return;
-                       }
-                       if (extra & 0x0800) { /* FPSR */
-                               FAIL (1);
-                               return;
-                       }
-                       if (extra & 0x0400) { /* FPIAR */
-                               mov_l_rm (opcode & 15, uae_p32(&regs.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,<ea> */
+               /* 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 <ea>,<reglist> */
+       case 7:                                                 /* FMOVEM <reglist>,<ea> */
+               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  <EA>, 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 <ea>,<control> */
+       case 5:                                                 /* FMOVEM <control>,<ea> */
+               if (jit_disable.fmovec)
+               {
+                       FAIL(1);
+                       return;
+               }
+
+               /* rare */
+               if ((opcode & 0x30) == 0)
+               {
+                       /* <ea> = 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)&regs.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)&regs.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, <EA> */
-               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)
+               {
+                       /* <ea> = #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)&regs.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)&regs.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 <EA> 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  <EA>,FPx */
-                       fmov_rr (FP_RESULT, dreg);
-                       return;
-               }
-               /* no break here for <EA> to dreg */
-               case 0: /* directly from sreg to dreg */
-               if (!source) { /* no <EA> */
-                       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(&regs.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(&regs.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 <EA> */
-                                       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 <EA> */
-                                       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(&regs.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(&regs.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(&regs.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(&regs.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(&regs.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
index 38e8bc9370e2e43c2c9e9d3d37709cdf94a66a65..afb990340b050723baae196f29bd5561a3a0a245 100644 (file)
@@ -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);
+}
index a477f6edb285ee53f62f48239cb3583045ba851b..82b75415b548dbbe12058c9f2aef73f7021e9aa3 100644 (file)
@@ -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));
index fc1eec21a68d815dd84a63389f02785344e70c1a..964123512c7d213bf68d0fa3380cfa41c84d58ee 100644 (file)
 #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"
 #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;i<VREGS;i++)
+               if (live.state[i].status==DIRTY) {
+                       if (!call_saved[live.state[i].realreg]) {
+                               tomem(i);
+                       }
+               }
+       for (i=0;i<VFREGS;i++)
+               if (f_isinreg(i))
+                       f_evict(i);
+       raw_fp_cleanup_drop();
+}
+
+/* Make sure all registers that will get clobbered by a call are
+   save and sound in memory */
+static void prepare_for_call_1(void)
+{
+       flush_all();  /* If there are registers that don't get clobbered,
+                          * we should be a bit more selective here */
+}
+
+/* We will call a C routine in a moment. That will clobber all registers,
+   so we need to disassociate everything */
+static void prepare_for_call_2(void)
+{
+       int i;
+       for (i=0;i<N_REGS;i++)
+               if (!call_saved[i] && live.nat[i].nholds>0)
+                       free_nreg(i);
+
+       for (i=0;i<N_FREGS;i++)
+               if (live.fat[i].nholds>0)
+                       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(&regflags.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(&regflags.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(&regs.c));
+       shll_l_ri(tmp, 0);
+       or_l(sr, tmp);
+       mov_b_rm(tmp, uae_p32(&regs.v));
+       shll_l_ri(tmp, 1);
+       or_l(sr, tmp);
+       mov_b_rm(tmp, uae_p32(&regs.z));
+       shll_l_ri(tmp, 2);
+       or_l(sr, tmp);
+       mov_b_rm(tmp, uae_p32(&regs.n));
+       shll_l_ri(tmp, 3);
+       or_l(sr, tmp);
+
+#endif /* OPTIMIZED_FLAGS */
+
+       mov_b_rm(tmp, uae_p32(&regs.s));
+       shll_l_ri(tmp, 13);
+       or_l(sr, tmp);
+       mov_l_rm(tmp, uae_p32(&regs.intmask));
+       shll_l_ri(tmp, 8);
+       or_l(sr, tmp);
+       and_l_ri(sr, 0x271f);
+       mov_w_mr(uae_p32(&regs.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)&regs.usp, SP_REG);
+       mov_l_rm(SP_REG, uae_p32(&regs.isp));
+       mov_b_mi(uae_p32(&regs.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("<JIT compiler> : 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("<JIT compiler> : 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("<JIT compiler> : 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("<JIT compiler> : 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*)(&regs.fp_result.fp);
+                       live.fate[i].mem=(uae_u32*)(&regs.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<VREGS;i++) {
-                       if (live.state[i].needflush==NF_TOMEM) {
-                               switch(live.state[i].status) {
-                               case INMEM:
-                                       if (live.state[i].val) {
-                                               compemu_raw_add_l_mi((uintptr)live.state[i].mem,live.state[i].val);
-                                               log_vwrite(i);
-                                               live.state[i].val=0;
-                                       }
-                                       break;
-                               case CLEAN:
-                               case DIRTY:
-                                       remove_offset(i,-1);
-                                       tomem(i);
-                                       break;
-                               case ISCONST:
-                                       if (i!=PC_P)
-                                               writeback_const(i);
-                                       break;
-                               default: break;
-                               }
-                               Dif (live.state[i].val && i!=PC_P) {
-                                       jit_log("Register %d still has val %x", i,live.state[i].val);
-                               }
-                       }
+                       flush_reg(i);
                }
                for (i=0;i<VFREGS;i++) {
                        if (live.fate[i].needflush==NF_TOMEM &&
@@ -3000,7 +3220,7 @@ static void flush_keepflags(void)
 }
 #endif
 
-void freescratch(void)
+static void freescratch(void)
 {
        int i;
        for (i=0;i<N_REGS;i++)
@@ -3028,78 +3248,6 @@ void freescratch(void)
                }
 }
 
-/********************************************************************
- * 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
-}
-
-static void flush_all(void)
-{
-       int i;
-
-       log_flush();
-       for (i=0;i<VREGS;i++)
-               if (live.state[i].status==DIRTY) {
-                       if (!call_saved[live.state[i].realreg]) {
-                               tomem(i);
-                       }
-               }
-       for (i=0;i<VFREGS;i++)
-               if (f_isinreg(i))
-                       f_evict(i);
-       raw_fp_cleanup_drop();
-}
-
-/* Make sure all registers that will get clobbered by a call are
-   save and sound in memory */
-static void prepare_for_call_1(void)
-{
-       flush_all();  /* If there are registers that don't get clobbered,
-                          * we should be a bit more selective here */
-}
-
-/* We will call a C routine in a moment. That will clobber all registers,
-   so we need to disassociate everything */
-static void prepare_for_call_2(void)
-{
-       int i;
-       for (i=0;i<N_REGS;i++)
-               if (!call_saved[i] && live.nat[i].nholds>0)
-                       free_nreg(i);
-
-       for (i=0;i<N_FREGS;i++)
-               if (live.fat[i].nholds>0)
-                       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(&regs.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("<JIT compiler> : 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("<JIT compiler> : 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("<JIT compiler> : 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("<JIT compiler> : 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(&regs.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;
        }
index 904508ce282f7933fada048cf5bd894335ad11b3..678e5d2fa60e41c4e7d67ed582d728396881d3e5 100644 (file)
@@ -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
  *
 #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
 #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<comp_index;i++)
-       putchar(lines[i]);
-    com_discard();
+       printf("%s", outbuffer);
+       com_discard();
 }
 
 
@@ -186,147 +268,143 @@ static int *opcode_next_clev;
 static int *opcode_last_postfix;
 static unsigned long *counts;
 
-static void
-read_counts (void)
+static void read_counts(void)
 {
-    FILE *file;
-    unsigned long opcode, count, total;
-    char name[20];
-    int nr = 0;
-    memset (counts, 0, 65536 * sizeof *counts);
-
-    file = fopen ("frequent.68k", "r");
-    if (file)
-    {
-       if (fscanf (file, "Total: %lu\n", &total) != 1) {
-               assert(0);
-       }
-       while (fscanf (file, "%lx: %lu %s\n", &opcode, &count, name) == 3)
+       FILE *file;
+       unsigned long opcode, count, total;
+       char name[20];
+       int nr = 0;
+       memset(counts, 0, 65536 * sizeof * counts);
+
+       file = fopen("frequent.68k", "r");
+       if (file)
        {
-           opcode_next_clev[nr] = NEXT_CPU_LEVEL;
-           opcode_last_postfix[nr] = -1;
-           opcode_map[nr++] = opcode;
-           counts[opcode] = count;
+               if (fscanf(file, "Total: %lu\n", &total) != 1) {
+                       assert(0);
+               }
+               while (fscanf(file, "%lx: %lu %s\n", &opcode, &count, name) == 3)
+               {
+                       opcode_next_clev[nr] = NEXT_CPU_LEVEL;
+                       opcode_last_postfix[nr] = -1;
+                       opcode_map[nr++] = opcode;
+                       counts[opcode] = count;
+               }
+               fclose(file);
        }
-       fclose (file);
-    }
-    if (nr == nr_cpuop_funcs)
-       return;
-    for (opcode = 0; opcode < 0x10000; opcode++)
-    {
-       if (table68k[opcode].handler == -1 && table68k[opcode].mnemo != i_ILLG
-           && counts[opcode] == 0)
+       if (nr == nr_cpuop_funcs)
+               return;
+       for (opcode = 0; opcode < 0x10000; opcode++)
        {
-           opcode_next_clev[nr] = NEXT_CPU_LEVEL;
-           opcode_last_postfix[nr] = -1;
-           opcode_map[nr++] = opcode;
-           counts[opcode] = count;
+               if (table68k[opcode].handler == -1 && table68k[opcode].mnemo != i_ILLG
+                       && counts[opcode] == 0)
+               {
+                       opcode_next_clev[nr] = NEXT_CPU_LEVEL;
+                       opcode_last_postfix[nr] = -1;
+                       opcode_map[nr++] = opcode;
+                       counts[opcode] = count;
+               }
        }
-    }
-    assert (nr == nr_cpuop_funcs);
+       assert(nr == nr_cpuop_funcs);
 }
 
 static int n_braces = 0;
 static int insn_n_cycles;
 
-static void
-start_brace (void)
+static void start_brace(void)
 {
-    n_braces++;
-    comprintf ("{");
+       n_braces++;
+       comprintf("{\n");
 }
 
-static void
-close_brace (void)
+static void close_brace(void)
 {
-    assert (n_braces > 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)&regs.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)&regs.vbr);\n");
+               comprintf("    mov_l_brR(srca, srca, MEMBaseDiff + trapno * 4); mid_bswap_32(srca);\n");
+               comprintf("    mov_l_mr((uintptr)&regs.pc, srca);\n");
+               comprintf("    get_n_addr_jmp(srca, PC_P, scratchie);\n");
+               comprintf("    mov_l_mr((uintptr)&regs.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)&regs.pc,newad);\n"
-                 "\tget_n_addr_jmp(newad,PC_P,scratchie);\n"
-                 "\tmov_l_mr((uintptr)&regs.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)&regs.pc,newad);\n"
+                       "\tget_n_addr_jmp(newad,PC_P,scratchie);\n"
+                       "\tmov_l_mr((uintptr)&regs.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)&regs.pc,newad);\n"
-                 "\tget_n_addr_jmp(newad,PC_P,scratchie);\n"
-                 "\tmov_l_mr((uintptr)&regs.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)&regs.pc,newad);\n"
+                       "\tget_n_addr_jmp(newad,PC_P,scratchie);\n"
+                       "\tmov_l_mr((uintptr)&regs.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)&regs.pc,srca);\n"
-                 "\tget_n_addr_jmp(srca,PC_P,scratchie);\n"
-                 "\tmov_l_mr((uintptr)&regs.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)&regs.pc,srca);\n"
+                       "\tget_n_addr_jmp(srca,PC_P,scratchie);\n"
+                       "\tmov_l_mr((uintptr)&regs.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)&regs.pc,srca);\n"
-                 "\tget_n_addr_jmp(srca,PC_P,scratchie);\n"
-                 "\tmov_l_mr((uintptr)&regs.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)&regs.pc,srca);\n"
+                       "\tget_n_addr_jmp(srca,PC_P,scratchie);\n"
+                       "\tmov_l_mr((uintptr)&regs.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,"#<data>.B");
+                       strcpy(buffer, "#<data>.B");
                        break;
                case sz_word:
-                       strcpy (buffer,"#<data>.W");
+                       strcpy(buffer, "#<data>.W");
                        break;
                case sz_long:
-                       strcpy (buffer,"#<data>.L");
+                       strcpy(buffer, "#<data>.L");
                        break;
                default:
                        break;
                }
                break;
        case imm0:
-               strcpy (buffer,"#<data>.B");
+               strcpy(buffer, "#<data>.B");
                break;
        case imm1:
-               strcpy (buffer,"#<data>.W");
+               strcpy(buffer, "#<data>.W");
                break;
        case imm2:
-               strcpy (buffer,"#<data>.L");
+               strcpy(buffer, "#<data>.L");
                break;
        case immi:
-               strcpy (buffer,"#<data>");
+               strcpy(buffer, "#<data>");
                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 (file)
index 0000000..d211c7b
--- /dev/null
@@ -0,0 +1,2 @@
+#include "options.h"
+#include "memory.h"
index 55971c5fcb6b85f1eeaf81de983dcc3f045ad8a0..506305419cda8fe6e66ae8a0f2dd7a7580db97a9 100644 (file)
--- 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)
index 0a15b8d1414a3235c6f9041fd7fd0ef2f2ea4ed5..5c710be135ed0789e3a2c92d7643d91d7f4dbcb1 100644 (file)
@@ -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);
index 20e26e4a6187259f3dccd4dd9a71cf8f2b87301a..32adbe34ba4e569f2d519964ffb54ec36c55d2f1 100644 (file)
@@ -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 = &regs;
 
        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 = &regs;
        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;
index 25b268ea0c68642ad456c2a43e8933671d851331..7427add8a03cdbeefb197309f7f1fbadfcb8173e 100644 (file)
@@ -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;
                }
 
index b8198b63d0d620de2b7c98359545f97768777b3d..5094e027427e6fab9bc02e87a41635c527f3f78b 100644 (file)
@@ -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
index be00e9a5eb64d47ca0f8f76899d5f46fe715a92e..cea10e77c6f5f725f9cc157601adce93f560c32a 100644 (file)
  /*
   * 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
index 2a5223f7c56f4723060d2bbb707ed8cd9805c4ec..1b3cea31ce7740990c80cc0a0cd2b5c5b9020131 100644 (file)
@@ -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))
 
index ef2692b33fdd619e7acd09d2445bf645443c74e9..38cb09a5c7de7dee86cfa3a9453af80907599ddf 100644 (file)
@@ -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
index ddceee210e82195d65b6cef8ed142783e730524c..7bdaa53693e58ad60a48ed889319bbd133a3beda 100644 (file)
@@ -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;
+}
index 0ec4ffb62effc49a8ebd49f44bc7acdb61049ba5..79f825c7248db7d1600e65a2063fcda171b508a4 100644 (file)
--- 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
 %   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