Aranym JIT merge.

This commit is contained in:
Toni Wilen 2020-07-27 19:56:31 +03:00
parent 0a0b254e8b
commit 6bb71af5c2
27 changed files with 6645 additions and 7589 deletions

View 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;

View File

@ -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);
}
}

View 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);

View File

@ -12,6 +12,13 @@
#include "uae/types.h"
#ifndef D
#define D
#endif
#ifndef bug
#define bug write_log
#endif
#ifdef DEBUGGER
#define MAX_HIST 500

View 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)

View 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);

View 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

2
include/uae/memory.h Normal file
View File

@ -0,0 +1,2 @@
#include "options.h"
#include "../memory.h"

File diff suppressed because it is too large Load Diff

View 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) ))

View 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

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View 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));

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

2
jit/memory-uae.h Normal file
View File

@ -0,0 +1,2 @@
#include "options.h"
#include "memory.h"

View File

@ -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)

View 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);

View 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)
{
ExceptionX (nr, -1);
Exception_cpu_oldpc(nr, 0xffffffff);
}
void REGPARAM2 ExceptionL (int nr, uaecptr address)
void REGPARAM2 Exception(int nr)
{
ExceptionX (nr, address);
ExceptionX(nr, 0xffffffff, 0xffffffff);
}
void REGPARAM2 ExceptionL(int nr, uaecptr 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;

View 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;
}

View 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

View File

@ -10,38 +10,107 @@
/*
* Machine dependent structure for holding the 68k CCR flags
*/
extern int cctrue(int cc);
#ifndef SAHF_SETO_PROFITABLE
struct flag_struct {
unsigned int cznv;
unsigned int x;
#if defined(CPU_x86_64)
uae_u64 cznv;
uae_u64 x;
#else
uae_u32 cznv;
uae_u32 x;
#endif
};
extern struct flag_struct regflags;
#if 1
#define FLAGBIT_N 15
#define FLAGBIT_Z 14
#define FLAGBIT_C 8
#define FLAGBIT_V 0
#define FLAGBIT_X 8
#else
/*
* The bits in the cznv field in the above structure are assigned to
* allow the easy mirroring of the x86 rFLAGS register.
*
* The 68k CZNV flags are thus assigned in cznv as:
*
* 76543210 FEDCBA98 --------- ---------
* SZxxxxxC xxxxVxxx xxxxxxxxx xxxxxxxxx
*/
#define FLAGBIT_N 7
#define FLAGBIT_Z 6
#define FLAGBIT_C 0
#define FLAGBIT_V 11
#define FLAGBIT_X 0
#endif
#define FLAGVAL_N (1 << FLAGBIT_N)
#define FLAGVAL_Z (1 << FLAGBIT_Z)
#define FLAGVAL_Z (1 << FLAGBIT_Z)
#define FLAGVAL_C (1 << FLAGBIT_C)
#define FLAGVAL_V (1 << FLAGBIT_V)
#define FLAGVAL_X (1 << FLAGBIT_X)
#define SET_ZFLG(y) (regflags.cznv = (regflags.cznv & ~FLAGVAL_Z) | (((y) ? 1 : 0) << FLAGBIT_Z))
#define SET_CFLG(y) (regflags.cznv = (regflags.cznv & ~FLAGVAL_C) | (((y) ? 1 : 0) << FLAGBIT_C))
#define SET_VFLG(y) (regflags.cznv = (regflags.cznv & ~FLAGVAL_V) | (((y) ? 1 : 0) << FLAGBIT_V))
#define SET_NFLG(y) (regflags.cznv = (regflags.cznv & ~FLAGVAL_N) | (((y) ? 1 : 0) << FLAGBIT_N))
#define SET_XFLG(y) (regflags.x = ((y) ? 1 : 0) << FLAGBIT_X)
#define SET_ZFLG(y) (regflags.cznv = (regflags.cznv & ~FLAGVAL_Z) | (((y) & 1) << FLAGBIT_Z))
#define SET_CFLG(y) (regflags.cznv = (regflags.cznv & ~FLAGVAL_C) | (((y) & 1) << FLAGBIT_C))
#define SET_VFLG(y) (regflags.cznv = (regflags.cznv & ~FLAGVAL_V) | (((y) & 1) << FLAGBIT_V))
#define SET_NFLG(y) (regflags.cznv = (regflags.cznv & ~FLAGVAL_N) | (((y) & 1) << FLAGBIT_N))
#define SET_XFLG(y) (regflags.x = ((y) & 1) << FLAGBIT_X)
#define GET_ZFLG() ((regflags.cznv >> FLAGBIT_Z) & 1)
#define GET_CFLG() ((regflags.cznv >> FLAGBIT_C) & 1)
#define GET_VFLG() ((regflags.cznv >> FLAGBIT_V) & 1)
#define GET_NFLG() ((regflags.cznv >> FLAGBIT_N) & 1)
#define GET_XFLG() ((regflags.x >> FLAGBIT_X) & 1)
#define CLEAR_CZNV() (regflags.cznv = 0)
#define GET_CZNV() (regflags.cznv)
#define IOR_CZNV(X) (regflags.cznv |= (X))
#define SET_CZNV(X) (regflags.cznv = (X))
#define COPY_CARRY() (regflags.x = regflags.cznv >> (FLAGBIT_C - FLAGBIT_X))
#else /* !SAHF_SETO_PROFITABLE */
/*
* Machine dependent structure for holding the 68k CCR flags
*/
struct flag_struct {
uae_u32 cznv;
uae_u32 x;
};
extern struct flag_struct regflags;
/*
* The bits in the cznv field in the above structure are assigned to
* allow the easy mirroring of the x86 condition flags. (For example,
* from the AX register - the x86 overflow flag can be copied to AL
* with a setto %AL instr and the other flags copied to AH with an
* lahf instr).
*
* The 68k CZNV flags are thus assigned in cznv as:
*
* <--AL--> <--AH-->
* 76543210 FEDCBA98 --------- ---------
* xxxxxxxV NZxxxxxC xxxxxxxxx xxxxxxxxx
*/
#define FLAGBIT_N 15
#define FLAGBIT_Z 14
#define FLAGBIT_C 8
#define FLAGBIT_V 0
#define FLAGBIT_X 0 /* must be in position 0 for duplicate_carry() to work */
#define FLAGVAL_N (1 << FLAGBIT_N)
#define FLAGVAL_Z (1 << FLAGBIT_Z)
#define FLAGVAL_C (1 << FLAGBIT_C)
#define FLAGVAL_V (1 << FLAGBIT_V)
#define FLAGVAL_X (1 << FLAGBIT_X)
#define SET_ZFLG(y) (regflags.cznv = (((uae_u32)regflags.cznv) & ~FLAGVAL_Z) | (((y) & 1) << FLAGBIT_Z))
#define SET_CFLG(y) (regflags.cznv = (((uae_u32)regflags.cznv) & ~FLAGVAL_C) | (((y) & 1) << FLAGBIT_C))
#define SET_VFLG(y) (regflags.cznv = (((uae_u32)regflags.cznv) & ~FLAGVAL_V) | (((y) & 1) << FLAGBIT_V))
#define SET_NFLG(y) (regflags.cznv = (((uae_u32)regflags.cznv) & ~FLAGVAL_N) | (((y) & 1) << FLAGBIT_N))
#define SET_XFLG(y) (regflags.x = ((y) & 1) << FLAGBIT_X)
#define GET_ZFLG() ((regflags.cznv >> FLAGBIT_Z) & 1)
#define GET_CFLG() ((regflags.cznv >> FLAGBIT_C) & 1)
@ -49,11 +118,11 @@ extern struct flag_struct regflags;
#define GET_NFLG() ((regflags.cznv >> FLAGBIT_N) & 1)
#define GET_XFLG() ((regflags.x >> FLAGBIT_X) & 1)
#define CLEAR_CZNV() (regflags.cznv = 0)
#define GET_CZNV() (regflags.cznv)
#define IOR_CZNV(X) (regflags.cznv |= (X))
#define SET_CZNV(X) (regflags.cznv = (X))
#define CLEAR_CZNV() (regflags.cznv = 0)
#define GET_CZNV() (regflags.cznv)
#define IOR_CZNV(X) (regflags.cznv |= (X))
#define SET_CZNV(X) (regflags.cznv = (X))
#define COPY_CARRY() (regflags.x = regflags.cznv)
#define COPY_CARRY() (regflags.x = regflags.cznv >> (FLAGBIT_C - FLAGBIT_X))
extern int cctrue(int cc);
#endif

View 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))

View 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

View 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,30 +778,50 @@ endofline:
table68k[opc].flaginfo[i].flaguse = id.flaginfo[i].flaguse;
}
#endif
// 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 */
}
}
#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;
table68k[opc].isjmp = isjmp;
nomatch:
#endif
table68k[opc].cflow = cflow;
nomatch:
/* FOO! */;
}
}
void read_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);
}
}
static int imismatch;
static void handle_merges (long int opcode)
@ -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;
}

484
table68k
View File

@ -4,6 +4,7 @@
% C: condition codes, except F
% f: direction
% i: immediate
% E: immediate, except 00 (Aranym only, EmulOp instruction)
% I: immediate, except 00 and ff
% j: immediate 1..8
% J: immediate 0..15
@ -53,467 +54,480 @@
% 0 means flag reset
% 1 means flag set
% ? means programmer was too lazy to check or instruction may trap
% + means instruction is conditional branch
% everything else means flag set/used
% / means instruction is unconditional branch/call
% + means instruction is conditional branch (ignored, only for sync)
% / means instruction is unconditional branch/call (ignored, only for sync)
% x means flag is unknown and well-behaved programs shouldn't check it
% everything else means flag set/used
%
% Control flow
% two letters, combination of
% - nothing
% T the instruction may trap or cause an exception
% B branch instruction
% J jump instruction
% R return instruction
%
% srcaddr status destaddr status :
% bitmasks of
% 1 means fetched
% 2 means stored
% 4 means jump offset
% 8 means jump address
%
% instruction
% optional line feed and 68030 Head/Tail/Cycles/ea calculation
%
0000 0000 0011 1100:000:XNZVC:XNZVC:10: ORSR.B #1
0000 0000 0111 1100:002:?????:?????:10: ORSR.W #1
0000 0zz0 11ss sSSS:250:?????:?????:11: CHK2.z #1,s[!Dreg,Areg,Aipi,Apdi,Immd]
0000 0000 0011 1100:000:XNZVC:XNZVC:--:10: ORSR.B #1
0000 0000 0111 1100:002:XNZVC:XNZVC:T-:10: ORSR.W #1
0000 0zz0 11ss sSSS:250:-?Z?C:-----:T-:11: CHK2.z #1,s[!Dreg,Areg,Aipi,Apdi,Immd]
0000 0000 zzdd dDDD:000:-NZ00:-----:13: OR.z #z,d[Dreg]
0000 0000 zzdd dDDD:000:-NZ00:-----:--:13: OR.z #z,d[Dreg]
- 2 0 2 fiea
0000 0000 zzdd dDDD:000:-NZ00:-----:13: OR.z #z,d[!Areg,Dreg]
0000 0000 zzdd dDDD:000:-NZ00:-----:--:13: OR.z #z,d[!Areg,Dreg]
- 0 1 3 fiea
0000 0010 0011 1100:000:XNZVC:XNZVC:10: ANDSR.B #1
0000 0010 0111 1100:002:?????:?????:10: ANDSR.W #1
0000 0010 0011 1100:000:XNZVC:XNZVC:--:10: ANDSR.B #1
0000 0010 0111 1100:002:XNZVC:XNZVC:T-:10: ANDSR.W #1
0000 0010 zzdd dDDD:000:-NZ00:-----:13: AND.z #z,d[Dreg]
0000 0010 zzdd dDDD:000:-NZ00:-----:--:13: AND.z #z,d[Dreg]
- 2 0 2 fiea
0000 0010 zzdd dDDD:000:-NZ00:-----:13: AND.z #z,d[!Areg,Dreg]
0000 0010 zzdd dDDD:000:-NZ00:-----:--:13: AND.z #z,d[!Areg,Dreg]
- 0 1 3 fiea
0000 0100 zzdd dDDD:000:XNZVC:-----:13: SUB.z #z,d[Dreg]
0000 0100 zzdd dDDD:000:XNZVC:-----:--:13: SUB.z #z,d[Dreg]
- 2 0 2 fiea
0000 0100 zzdd dDDD:000:XNZVC:-----:13: SUB.z #z,d[!Areg,Dreg]
0000 0100 zzdd dDDD:000:XNZVC:-----:--:13: SUB.z #z,d[!Areg,Dreg]
- 0 1 3 fiea
0000 0110 zzdd dDDD:000:XNZVC:-----:13: ADD.z #z,d[Dreg]
0000 0110 zzdd dDDD:000:XNZVC:-----:--:13: ADD.z #z,d[Dreg]
- 2 0 2 fiea
0000 0110 zzdd dDDD:000:XNZVC:-----:13: ADD.z #z,d[!Areg,Dreg]
0000 0110 zzdd dDDD:000:XNZVC:-----:--:13: ADD.z #z,d[!Areg,Dreg]
- 0 1 3 fiea
0000 0110 11ss sSSS:230:?????:?????:10: CALLM s[!Dreg,Areg,Aipi,Apdi,Immd]
0000 0110 11ss sSSS:230:?????:?????:10: RTM s[Dreg,Areg]
0000 0110 11ss sSSS:230:-----:XNZVC:--:10: CALLM s[!Dreg,Areg,Aipi,Apdi,Immd]
0000 0110 11ss sSSS:230:XNZVC:-----:-R:10: RTM s[Dreg,Areg]
0000 1000 00ss sSSS:000:--Z--:-----:11: BTST #1,s[Dreg]
0000 1000 00ss sSSS:000:--Z--:-----:--:11: BTST #1,s[Dreg]
- 4 0 4
0000 1000 00ss sSSS:000:--Z--:-----:11: BTST #1,s[!Areg,Dreg,Immd]
0000 1000 00ss sSSS:000:--Z--:-----:--:11: BTST #1,s[!Areg,Dreg,Immd]
- 0 0 4 fiea
0000 1000 01ss sSSS:000:--Z--:-----:13: BCHG #1,s[Dreg]
0000 1000 01ss sSSS:000:--Z--:-----:--:13: BCHG #1,s[Dreg]
- 6 0 6
0000 1000 01ss sSSS:000:--Z--:-----:13: BCHG #1,s[!Areg,Dreg,Immd,PC8r,PC16]
0000 1000 01ss sSSS:000:--Z--:-----:--:13: BCHG #1,s[!Areg,Dreg,Immd,PC8r,PC16]
- 0 0 6 fiea
0000 1000 10ss sSSS:000:--Z--:-----:13: BCLR #1,s[Dreg]
0000 1000 10ss sSSS:000:--Z--:-----:--:13: BCLR #1,s[Dreg]
- 6 0 6
0000 1000 10ss sSSS:000:--Z--:-----:13: BCLR #1,s[!Areg,Dreg,Immd,PC8r,PC16]
0000 1000 10ss sSSS:000:--Z--:-----:--:13: BCLR #1,s[!Areg,Dreg,Immd,PC8r,PC16]
- 0 0 6 fiea
0000 1000 11ss sSSS:000:--Z--:-----:13: BSET #1,s[Dreg]
0000 1000 11ss sSSS:000:--Z--:-----:--:13: BSET #1,s[Dreg]
- 6 0 6
0000 1000 11ss sSSS:000:--Z--:-----:13: BSET #1,s[!Areg,Dreg,Immd,PC8r,PC16]
0000 1000 11ss sSSS:000:--Z--:-----:--:13: BSET #1,s[!Areg,Dreg,Immd,PC8r,PC16]
- 0 0 6 fiea
0000 1010 0011 1100:000:XNZVC:XNZVC:10: EORSR.B #1
0000 1010 0111 1100:002:?????:?????:10: EORSR.W #1
0000 1010 0011 1100:000:XNZVC:XNZVC:--:10: EORSR.B #1
0000 1010 0111 1100:002:XNZVC:XNZVC:T-:10: EORSR.W #1
0000 1010 zzdd dDDD:000:-NZ00:-----:13: EOR.z #z,d[Dreg]
0000 1010 zzdd dDDD:000:-NZ00:-----:--:13: EOR.z #z,d[Dreg]
- 2 0 2 fiea
0000 1010 zzdd dDDD:000:-NZ00:-----:13: EOR.z #z,d[!Areg,Dreg]
0000 1010 zzdd dDDD:000:-NZ00:-----:--:13: EOR.z #z,d[!Areg,Dreg]
- 0 1 3 fiea
0000 1100 zzss sSSS:000:-NZVC:-----:11: CMP.z #z,s[Dreg]
0000 1100 zzss sSSS:000:-NZVC:-----:--:11: CMP.z #z,s[Dreg]
- 2 0 2 fiea
0000 1100 zzss sSSS:000:-NZVC:-----:11: CMP.z #z,s[!Areg,Dreg,Immd,PC8r,PC16]
0000 1100 zzss sSSS:000:-NZVC:-----:--:11: CMP.z #z,s[!Areg,Dreg,Immd,PC8r,PC16]
- 0 0 2 fiea
0000 1100 zzss sSSS:200:-NZVC:-----:11: CMP.z #z,s[PC8r,PC16]
0000 1100 zzss sSSS:200:-NZVC:-----:--:11: CMP.z #z,s[PC8r,PC16]
- 0 0 2 fiea
0000 1010 11ss sSSS:200:?????:?????:13: CAS.B #1,s[!Dreg,Areg,Immd,PC8r,PC16]
0000 1100 11ss sSSS:200:?????:?????:13: CAS.W #1,s[!Dreg,Areg,Immd,PC8r,PC16]
0000 1100 1111 1100:250:?????:?????:10: CAS2.W #2
0000 1110 zzss sSSS:102:?????:?????:13: MOVES.z #1,s[!Dreg,Areg,Immd,PC8r,PC16]
0000 1110 11ss sSSS:200:?????:?????:13: CAS.L #1,s[!Dreg,Areg,Immd,PC8r,PC16]
0000 1110 1111 1100:250:?????:?????:10: CAS2.L #2
0000 1010 11ss sSSS:200:-NZVC:-----:--:13: CAS.B #1,s[!Dreg,Areg,Immd,PC8r,PC16]
0000 1100 11ss sSSS:200:-NZVC:-----:--:13: CAS.W #1,s[!Dreg,Areg,Immd,PC8r,PC16]
0000 1100 1111 1100:250:-NZVC:-----:--:10: CAS2.W #2
0000 1110 zzss sSSS:102:-----:-----:T-:13: MOVES.z #1,s[!Dreg,Areg,Immd,PC8r,PC16]
0000 1110 11ss sSSS:200:-NZVC:-----:--:13: CAS.L #1,s[!Dreg,Areg,Immd,PC8r,PC16]
0000 1110 1111 1100:250:-NZVC:-----:--:10: CAS2.L #2
0000 rrr1 00dd dDDD:050:-----:-----:12: MVPMR.W d[Areg-Ad16],Dr
0000 rrr1 01dd dDDD:050:-----:-----:12: MVPMR.L d[Areg-Ad16],Dr
0000 rrr1 10dd dDDD:050:-----:-----:12: MVPRM.W Dr,d[Areg-Ad16]
0000 rrr1 11dd dDDD:050:-----:-----:12: MVPRM.L Dr,d[Areg-Ad16]
0000 rrr1 00dd dDDD:050:-----:-----:--:12: MVPMR.W d[Areg-Ad16],Dr
0000 rrr1 01dd dDDD:050:-----:-----:--:12: MVPMR.L d[Areg-Ad16],Dr
0000 rrr1 10dd dDDD:050:-----:-----:--:12: MVPRM.W Dr,d[Areg-Ad16]
0000 rrr1 11dd dDDD:050:-----:-----:--:12: MVPRM.L Dr,d[Areg-Ad16]
0000 rrr1 00ss sSSS:000:--Z--:-----:11: BTST Dr,s[Dreg]
0000 rrr1 00ss sSSS:000:--Z--:-----:--:11: BTST Dr,s[Dreg]
- 4 0 4
0000 rrr1 00ss sSSS:000:--Z--:-----:11: BTST Dr,s[!Areg,Dreg]
0000 rrr1 00ss sSSS:000:--Z--:-----:--:11: BTST Dr,s[!Areg,Dreg]
- 0 0 4 fea
0000 rrr1 01ss sSSS:000:--Z--:-----:13: BCHG Dr,s[Dreg]
0000 rrr1 01ss sSSS:000:--Z--:-----:--:13: BCHG Dr,s[Dreg]
- 6 0 6
0000 rrr1 01ss sSSS:000:--Z--:-----:13: BCHG Dr,s[!Areg,Dreg,Immd,PC8r,PC16]
0000 rrr1 01ss sSSS:000:--Z--:-----:--:13: BCHG Dr,s[!Areg,Dreg,Immd,PC8r,PC16]
- 0 0 6 fea
0000 rrr1 10ss sSSS:000:--Z--:-----:13: BCLR Dr,s[Dreg]
0000 rrr1 10ss sSSS:000:--Z--:-----:--:13: BCLR Dr,s[Dreg]
- 6 0 6
0000 rrr1 10ss sSSS:000:--Z--:-----:13: BCLR Dr,s[!Areg,Dreg,Immd,PC8r,PC16]
0000 rrr1 10ss sSSS:000:--Z--:-----:--:13: BCLR Dr,s[!Areg,Dreg,Immd,PC8r,PC16]
- 0 0 6 fea
0000 rrr1 11ss sSSS:000:--Z--:-----:13: BSET Dr,s[Dreg]
0000 rrr1 11ss sSSS:000:--Z--:-----:--:13: BSET Dr,s[Dreg]
- 6 0 6
0000 rrr1 11ss sSSS:000:--Z--:-----:13: BSET Dr,s[!Areg,Dreg,Immd,PC8r,PC16]
0000 rrr1 11ss sSSS:000:--Z--:-----:--:13: BSET Dr,s[!Areg,Dreg,Immd,PC8r,PC16]
- 0 0 6 fea
% Move cycles are special cased in gencpu.c
0001 DDDd ddss sSSS:000:-NZ00:-----:12: MOVE.B s,d[!Areg]
0011 DDDd ddss sSSS:000:-----:-----:12: MOVEA.W s,d[Areg]
0011 DDDd ddss sSSS:000:-NZ00:-----:12: MOVE.W s,d[!Areg]
0010 DDDd ddss sSSS:000:-----:-----:12: MOVEA.L s,d[Areg]
0010 DDDd ddss sSSS:000:-NZ00:-----:12: MOVE.L s,d[!Areg]
0001 DDDd ddss sSSS:000:-NZ00:-----:--:12: MOVE.B s,d[!Areg]
0011 DDDd ddss sSSS:000:-----:-----:--:12: MOVEA.W s,d[Areg]
0011 DDDd ddss sSSS:000:-NZ00:-----:--:12: MOVE.W s,d[!Areg]
0010 DDDd ddss sSSS:000:-----:-----:--:12: MOVEA.L s,d[Areg]
0010 DDDd ddss sSSS:000:-NZ00:-----:--:12: MOVE.L s,d[!Areg]
0100 0000 zzdd dDDD:000:XxZxC:X-Z--:30: NEGX.z d[Dreg]
0100 0000 zzdd dDDD:000:XNZVC:X-Z--:--:30: NEGX.z d[Dreg]
- 2 0 2
0100 0000 zzdd dDDD:000:XxZxC:X-Z--:30: NEGX.z d[!Areg,Dreg]
0100 0000 zzdd dDDD:000:XNZVC:X-Z--:--:30: NEGX.z d[!Areg,Dreg]
- 0 1 3 fea
0100 0000 11dd dDDD:001:?????:?????:10: MVSR2.W d[Dreg]
0100 0000 11dd dDDD:001:-----:XNZVC:T-:10: MVSR2.W d[Dreg]
- 2 0 4
0100 0000 11dd dDDD:001:?????:?????:10: MVSR2.W d[!Areg,Dreg]
0100 0000 11dd dDDD:001:-----:XNZVC:T-:10: MVSR2.W d[!Areg,Dreg]
- 2 0 4 cea
0100 0010 zzdd dDDD:000:-0100:-----:20: CLR.z d[Dreg]
0100 0010 zzdd dDDD:000:-0100:-----:--:20: CLR.z d[Dreg]
- 2 0 2
0100 0010 zzdd dDDD:000:-0100:-----:20: CLR.z d[!Areg,Dreg]
0100 0010 zzdd dDDD:000:-0100:-----:--:20: CLR.z d[!Areg,Dreg]
- 0 1 3 cea
0100 0010 11dd dDDD:100:?????:?????:10: MVSR2.B d[Dreg]
0100 0010 11dd dDDD:100:-----:XNZVC:--:10: MVSR2.B d[Dreg]
- 2 0 4
0100 0010 11dd dDDD:100:?????:?????:10: MVSR2.B d[!Areg,Dreg]
0100 0010 11dd dDDD:100:-----:XNZVC:--:10: MVSR2.B d[!Areg,Dreg]
- 2 0 4 cea
0100 0100 zzdd dDDD:000:XNZVC:-----:30: NEG.z d[Dreg]
0100 0100 zzdd dDDD:000:XNZVC:-----:--:30: NEG.z d[Dreg]
- 2 0 2
0100 0100 zzdd dDDD:000:XNZVC:-----:30: NEG.z d[!Areg,Dreg]
0100 0100 zzdd dDDD:000:XNZVC:-----:--:30: NEG.z d[!Areg,Dreg]
- 0 1 3 fea
0100 0100 11ss sSSS:000:XNZVC:-----:10: MV2SR.B s[Dreg]
0100 0100 11ss sSSS:000:XNZVC:-----:--:10: MV2SR.B s[Dreg]
- 4 0 4
0100 0100 11ss sSSS:000:XNZVC:-----:10: MV2SR.B s[!Areg,Dreg]
0100 0100 11ss sSSS:000:XNZVC:-----:--:10: MV2SR.B s[!Areg,Dreg]
- 0 0 4 fea
0100 0110 zzdd dDDD:000:-NZ00:-----:30: NOT.z d[Dreg]
0100 0110 zzdd dDDD:000:-NZ00:-----:--:30: NOT.z d[Dreg]
- 2 0 2
0100 0110 zzdd dDDD:000:-NZ00:-----:30: NOT.z d[!Areg,Dreg]
0100 0110 zzdd dDDD:000:-NZ00:-----:--:30: NOT.z d[!Areg,Dreg]
- 0 1 3 fea
0100 0110 11ss sSSS:002:?????:?????:10: MV2SR.W s[!Areg]
0100 0110 11ss sSSS:002:XNZVC:XNZVC:T-:10: MV2SR.W s[!Areg]
- 0 0 8 fea
0100 1000 0000 1rrr:200:-----:-----:31: LINK.L Ar,#2
0100 1000 0000 1rrr:200:-----:-----:--:31: LINK.L Ar,#2
- 2 0 6
0100 1000 00dd dDDD:000:X?Z?C:X-Z--:30: NBCD.B d[!Areg]
0100 1000 00dd dDDD:000:X?Z?C:X-Z--:--:30: NBCD.B d[!Areg]
- 0 0 6
0100 1000 0100 1kkk:100:?????:?????:10: BKPT #k
0100 1000 0100 1kkk:100:-----:-----:T-:10: BKPT #k
0100 1000 01ss sSSS:000:-NZ00:-----:30: SWAP.W s[Dreg]
0100 1000 01ss sSSS:000:-NZ00:-----:--:30: SWAP.W s[Dreg]
- 4 0 4
0100 1000 01ss sSSS:000:-----:-----:00: PEA.L s[!Dreg,Areg,Aipi,Apdi,Immd]
0100 1000 01ss sSSS:000:-----:-----:--:00: PEA.L s[!Dreg,Areg,Aipi,Apdi,Immd]
- 0 2 4 cea
0100 1000 10dd dDDD:000:-NZ00:-----:30: EXT.W d[Dreg]
0100 1000 10dd dDDD:000:-NZ00:-----:--:30: EXT.W d[Dreg]
- 4 0 4
0100 1000 10dd dDDD:000:-----:-----:02: MVMLE.W #1,d[!Dreg,Areg,Aipi]
0100 1000 10dd dDDD:000:-----:-----:--:02: MVMLE.W #1,d[!Dreg,Areg,Aipi]
0100 1000 11dd dDDD:000:-NZ00:-----:30: EXT.L d[Dreg]
0100 1000 11dd dDDD:000:-NZ00:-----:--:30: EXT.L d[Dreg]
- 4 0 4
0100 1000 11dd dDDD:000:-----:-----:02: MVMLE.L #1,d[!Dreg,Areg,Aipi]
0100 1000 11dd dDDD:000:-----:-----:--:02: MVMLE.L #1,d[!Dreg,Areg,Aipi]
0100 1001 11dd dDDD:200:-NZ00:-----:30: EXT.B d[Dreg]
0100 1001 11dd dDDD:200:-NZ00:-----:--:30: EXT.B d[Dreg]
- 4 0 4
0100 1010 zzss sSSS:000:-NZ00:-----:10: TST.z s[Dreg]
0100 1010 zzss sSSS:000:-NZ00:-----:--:10: TST.z s[Dreg]
- 0 0 2
0100 1010 zzss sSSS:000:-NZ00:-----:10: TST.z s[!Areg,Dreg,PC16,PC8r,Immd]
0100 1010 zzss sSSS:000:-NZ00:-----:--:10: TST.z s[!Areg,Dreg,PC16,PC8r,Immd]
- 0 0 2 fea
0100 1010 zzss sSSS:200:-NZ00:-----:10: TST.z s[Areg,PC16,PC8r,Immd]
0100 1010 zzss sSSS:200:-NZ00:-----:--:10: TST.z s[Areg,PC16,PC8r,Immd]
- 0 0 2 fea
0100 1010 11dd dDDD:000:?????:?????:30: TAS.B d[Dreg]
0100 1010 11dd dDDD:000:-NZ00:-----:--:30: TAS.B d[Dreg]
- 0 0 2
0100 1010 11dd dDDD:000:?????:?????:30: TAS.B d[!Areg,Dreg]
0100 1010 11dd dDDD:000:-NZ00:-----:--:30: TAS.B d[!Areg,Dreg]
- 0 0 2 fea
0100 1010 1111 1100:000:?????:?????:00: ILLEGAL
0100 1010 1111 1100:000:-----:-----:T-:00: ILLEGAL
0100 1100 00ss sSSS:200:-NZVC:-----:13: MULL.L #1,s[!Areg]
0100 1100 00ss sSSS:200:-NZVC:-----:--:13: MULL.L #1,s[!Areg]
- 2 0 30 fiea
0100 1100 01ss sSSS:200:?????:?????:13: DIVL.L #1,s[!Areg]
0100 1100 01ss sSSS:200:-NZV0:-----:T-:13: DIVL.L #1,s[!Areg]
- 0 0 50 fiea
0100 1100 10ss sSSS:000:-----:-----:01: MVMEL.W #1,s[!Dreg,Areg,Apdi,Immd]
0100 1100 11ss sSSS:000:-----:-----:01: MVMEL.L #1,s[!Dreg,Areg,Apdi,Immd]
0100 1110 0100 JJJJ:000:-----:XNZVC:10: TRAP #J
0100 1100 10ss sSSS:000:-----:-----:--:01: MVMEL.W #1,s[!Dreg,Areg,Apdi,Immd]
0100 1100 11ss sSSS:000:-----:-----:--:01: MVMEL.L #1,s[!Dreg,Areg,Apdi,Immd]
0100 1110 0100 JJJJ:000:-----:XNZVC:--:10: TRAP #J
0100 1110 0101 0rrr:000:-----:-----:31: LINK.W Ar,#1
0100 1110 0101 0rrr:000:-----:-----:--:31: LINK.W Ar,#1
- 0 0 4
0100 1110 0101 1rrr:000:-----:-----:30: UNLK.L Ar
0100 1110 0101 1rrr:000:-----:-----:--:30: UNLK.L Ar
- 0 0 5
0100 1110 0110 0rrr:002:-----:-----:10: MVR2USP.L Ar
0100 1110 0110 0rrr:002:-----:-----:T-:10: MVR2USP.L Ar
- 4 0 4
0100 1110 0110 1rrr:002:-----:-----:20: MVUSP2R.L Ar
0100 1110 0110 1rrr:002:-----:-----:T-:20: MVUSP2R.L Ar
- 4 0 4
0100 1110 0111 0000:002:-----:-----:00: RESET
0100 1110 0111 0000:002:-----:-----:T-:00: RESET
- 0 0 518
0100 1110 0111 0001:000:-----:-----:00: NOP
0100 1110 0111 0001:000:-----:-----:--:00: NOP
- 0 0 2
0100 1110 0111 0010:002:XNZVC:-----:10: STOP #1
0100 1110 0111 0010:002:XNZVC:-----:T-:10: STOP #1
- 0 0 8
0100 1110 0111 0011:002:XNZVC:-----:00: RTE
0100 1110 0111 0011:002:XNZVC:-----:TR:00: RTE
- 1 9 18
0100 1110 0111 0100:100:?????:?????:10: RTD #1
0100 1110 0111 0100:100:-----:-----:-R:10: RTD #1
- 2 0 10
0100 1110 0111 0101:000:-----:-----:00: RTS
0100 1110 0111 0101:000:-----:-----:-R:00: RTS
- 1 0 9
0100 1110 0111 0110:000:-----:XNZVC:00: TRAPV
0100 1110 0111 0110:000:-----:XNZVC:T-:00: TRAPV
0100 1110 0111 0111:000:XNZVC:-----:00: RTR
0100 1110 0111 0111:000:XNZVC:-----:-R:00: RTR
- 1 0 12
0100 1110 0111 1010:100:?????:?????:10: MOVEC2 #1
0100 1110 0111 1010:100:-----:-----:T-:10: MOVEC2 #1
- 6 0 6
0100 1110 0111 1011:100:?????:?????:10: MOVE2C #1
0100 1110 0111 1011:100:-----:-----:T-:10: MOVE2C #1
- 6 0 6
0100 1110 10ss sSSS:000://///://///:80: JSR.L s[!Dreg,Areg,Aipi,Apdi,Immd]
0100 1110 10ss sSSS:000://///://///:-J:80: JSR.L s[!Dreg,Areg,Aipi,Apdi,Immd]
- 0 0 4 jea
0100 rrr1 00ss sSSS:200:?????:?????:11: CHK.L s[!Areg],Dr
0100 rrr1 10ss sSSS:000:?????:?????:11: CHK.W s[!Areg],Dr
0100 rrr1 00ss sSSS:200:-N???:-----:T-:11: CHK.L s[!Areg],Dr
0100 rrr1 10ss sSSS:000:-N???:-----:T-:11: CHK.W s[!Areg],Dr
0100 1110 11ss sSSS:000://///://///:80: JMP.L s[!Dreg,Areg,Aipi,Apdi,Immd]
0100 1110 11ss sSSS:000://///://///:-J:80: JMP.L s[!Dreg,Areg,Aipi,Apdi,Immd]
- 4 0 4 jea
0100 rrr1 11ss sSSS:000:-----:-----:02: LEA.L s[!Dreg,Areg,Aipi,Apdi,Immd],Ar
0100 rrr1 11ss sSSS:000:-----:-----:--:02: LEA.L s[!Dreg,Areg,Aipi,Apdi,Immd],Ar
- 2 0 2 cea
0101 jjj0 01dd dDDD:000:-----:-----:13: ADDA.W #j,d[Areg]
% This variant of ADDQ is word and long sized only
0101 jjj0 01dd dDDD:000:-----:-----:--:13: ADDA.W #j,d[Areg]
- 2 0 2
0101 jjj0 10dd dDDD:000:-----:-----:13: ADDA.L #j,d[Areg]
0101 jjj0 10dd dDDD:000:-----:-----:--:13: ADDA.L #j,d[Areg]
- 2 0 2
0101 jjj0 zzdd dDDD:000:XNZVC:-----:13: ADD.z #j,d[Dreg]
0101 jjj0 zzdd dDDD:000:XNZVC:-----:--:13: ADD.z #j,d[Dreg]
- 2 0 2
0101 jjj0 zzdd dDDD:000:XNZVC:-----:13: ADD.z #j,d[!Areg,Dreg]
0101 jjj0 zzdd dDDD:000:XNZVC:-----:--:13: ADD.z #j,d[!Areg,Dreg]
- 0 1 3 fea
0101 jjj1 01dd dDDD:000:-----:-----:13: SUBA.W #j,d[Areg]
% This variant of SUBQ is word and long sized only
0101 jjj1 01dd dDDD:000:-----:-----:--:13: SUBA.W #j,d[Areg]
- 2 0 2
0101 jjj1 10dd dDDD:000:-----:-----:13: SUBA.L #j,d[Areg]
0101 jjj1 10dd dDDD:000:-----:-----:--:13: SUBA.L #j,d[Areg]
- 2 0 2
0101 jjj1 zzdd dDDD:000:XNZVC:-----:13: SUB.z #j,d[Dreg]
0101 jjj1 zzdd dDDD:000:XNZVC:-----:--:13: SUB.z #j,d[Dreg]
- 2 0 2
0101 jjj1 zzdd dDDD:000:XNZVC:-----:13: SUB.z #j,d[!Areg,Dreg]
0101 jjj1 zzdd dDDD:000:XNZVC:-----:--:13: SUB.z #j,d[!Areg,Dreg]
- 0 1 3 fea
0101 cccc 1100 1rrr:000:-----:-++++:31: DBcc.W Dr,#1
0101 cccc 1100 1rrr:000:-----:-++++:-B:31: DBcc.W Dr,#1
- -1 0 0
0101 cccc 11dd dDDD:000:-----:-++++:20: Scc.B d[Dreg]
0101 cccc 11dd dDDD:000:-----:-++++:--:20: Scc.B d[Dreg]
- 0 0 2
0101 cccc 11dd dDDD:000:-----:-++++:20: Scc.B d[!Areg,Dreg]
0101 cccc 11dd dDDD:000:-----:-++++:--:20: Scc.B d[!Areg,Dreg]
- 0 0 2 cea
0101 cccc 1111 1010:200:?????:?????:10: TRAPcc #1
0101 cccc 1111 1011:200:?????:?????:10: TRAPcc #2
0101 cccc 1111 1100:200:?????:?????:00: TRAPcc
0101 cccc 1111 1010:200:-----:-????:T-:10: TRAPcc #1
0101 cccc 1111 1011:200:-----:-????:T-:10: TRAPcc #2
0101 cccc 1111 1100:200:-----:-????:T-:00: TRAPcc
% Bxx.L is 68020 only, but setting the CPU level to 2 would give illegal
% instruction exceptions when compiling a 68000 only emulation, which isn't
% what we want either.
0110 0001 0000 0000:000://///://///:40: BSR.W #1
0110 0001 0000 0000:000://///://///:-B:40: BSR.W #1
- 2 0 6
0110 0001 IIII IIII:000://///://///:40: BSR.B #i
0110 0001 IIII IIII:000://///://///:-B:40: BSR.B #i
- 2 0 6
0110 0001 1111 1111:000://///://///:40: BSR.L #2
0110 0001 1111 1111:000://///://///:-B:40: BSR.L #2
- 2 0 6
0110 CCCC 0000 0000:000:-----:-++++:40: Bcc.W #1
0110 CCCC 0000 0000:000:-----:-++++:-B:40: Bcc.W #1
- -1 0 0
0110 CCCC IIII IIII:000:-----:-++++:40: Bcc.B #i
0110 CCCC IIII IIII:000:-----:-++++:-B:40: Bcc.B #i
- -1 0 0
0110 CCCC 1111 1111:000:-----:-++++:40: Bcc.L #2
0110 CCCC 1111 1111:000:-----:-++++:-B:40: Bcc.L #2
- -1 0 0
0111 rrr0 iiii iiii:000:-NZ00:-----:12: MOVE.L #i,Dr
0111 rrr0 iiii iiii:000:-NZ00:-----:--:12: MOVE.L #i,Dr
1000 rrr0 zzss sSSS:000:-NZ00:-----:13: OR.z s[Dreg],Dr
1000 rrr0 zzss sSSS:000:-NZ00:-----:--:13: OR.z s[Dreg],Dr
- 2 0 2
1000 rrr0 zzss sSSS:000:-NZ00:-----:13: OR.z s[!Areg,Dreg],Dr
1000 rrr0 zzss sSSS:000:-NZ00:-----:--:13: OR.z s[!Areg,Dreg],Dr
- 0 0 2 fea
1000 rrr0 11ss sSSS:000:?????:?????:13: DIVU.W s[Dreg],Dr
1000 rrr0 11ss sSSS:000:-NZV0:-----:T-:13: DIVU.W s[Dreg],Dr
- 2 0 20
1000 rrr0 11ss sSSS:000:?????:?????:13: DIVU.W s[!Areg,Dreg],Dr
1000 rrr0 11ss sSSS:000:-NZV0:-----:T-:13: DIVU.W s[!Areg,Dreg],Dr
- 0 0 20 fea
1000 rrr1 00dd dDDD:000:XxZxC:X-Z--:13: SBCD.B d[Dreg],Dr
1000 rrr1 00dd dDDD:000:X?Z?C:X-Z--:--:13: SBCD.B d[Dreg],Dr
- 0 0 4
1000 rrr1 00dd dDDD:000:XxZxC:X-Z--:13: SBCD.B d[Areg-Apdi],Arp
1000 rrr1 00dd dDDD:000:X?Z?C:X-Z--:--:13: SBCD.B d[Areg-Apdi],Arp
- 2 1 13
1000 rrr1 zzdd dDDD:000:-NZ00:-----:13: OR.z Dr,d[!Areg,Dreg]
1000 rrr1 zzdd dDDD:000:-NZ00:-----:--:13: OR.z Dr,d[!Areg,Dreg]
- 0 1 3 fea
1000 rrr1 01dd dDDD:200:?????:?????:12: PACK d[Dreg],Dr
1000 rrr1 01dd dDDD:200:-----:-----:--:12: PACK d[Dreg],Dr
- 6 0 6
1000 rrr1 01dd dDDD:200:?????:?????:12: PACK d[Areg-Apdi],Arp
1000 rrr1 01dd dDDD:200:-----:-----:--:12: PACK d[Areg-Apdi],Arp
- 2 1 11
1000 rrr1 10dd dDDD:200:?????:?????:12: UNPK d[Dreg],Dr
1000 rrr1 10dd dDDD:200:-----:-----:--:12: UNPK d[Dreg],Dr
- 8 0 8
1000 rrr1 10dd dDDD:200:?????:?????:12: UNPK d[Areg-Apdi],Arp
1000 rrr1 10dd dDDD:200:-----:-----:--:12: UNPK d[Areg-Apdi],Arp
- 2 1 11
1000 rrr1 11ss sSSS:000:?????:?????:13: DIVS.W s[Dreg],Dr
1000 rrr1 11ss sSSS:000:-NZV0:-----:T-:13: DIVS.W s[Dreg],Dr
- 2 0 20
1000 rrr1 11ss sSSS:000:?????:?????:13: DIVS.W s[!Areg,Dreg],Dr
1000 rrr1 11ss sSSS:000:-NZV0:-----:T-:13: DIVS.W s[!Areg,Dreg],Dr
- 0 0 20 fea
1001 rrr0 zzss sSSS:000:XNZVC:-----:13: SUB.z s[Areg,Dreg],Dr
1001 rrr0 zzss sSSS:000:XNZVC:-----:--:13: SUB.z s[Areg,Dreg],Dr
- 2 0 2
1001 rrr0 zzss sSSS:000:XNZVC:-----:13: SUB.z s[!Areg,Dreg],Dr
1001 rrr0 zzss sSSS:000:XNZVC:-----:--:13: SUB.z s[!Areg,Dreg],Dr
- 0 0 2 fea
1001 rrr0 11ss sSSS:000:-----:-----:13: SUBA.W s[Areg,Dreg],Ar
1001 rrr0 11ss sSSS:000:-----:-----:--:13: SUBA.W s[Areg,Dreg],Ar
- 4 0 4
1001 rrr0 11ss sSSS:000:-----:-----:13: SUBA.W s[!Areg,Dreg],Ar
1001 rrr0 11ss sSSS:000:-----:-----:--:13: SUBA.W s[!Areg,Dreg],Ar
- 0 0 4 fea
1001 rrr1 zzdd dDDD:000:XNZVC:X-Z--:13: SUBX.z d[Dreg],Dr
1001 rrr1 zzdd dDDD:000:XNZVC:X-Z--:--:13: SUBX.z d[Dreg],Dr
- 2 0 2
1001 rrr1 zzdd dDDD:000:XNZVC:X-Z--:13: SUBX.z d[Areg-Apdi],Arp
1001 rrr1 zzdd dDDD:000:XNZVC:X-Z--:--:13: SUBX.z d[Areg-Apdi],Arp
- 2 1 9
1001 rrr1 zzdd dDDD:000:XNZVC:-----:13: SUB.z Dr,d[!Areg,Dreg]
1001 rrr1 zzdd dDDD:000:XNZVC:-----:--:13: SUB.z Dr,d[!Areg,Dreg]
- 0 1 3 fea
1001 rrr1 11ss sSSS:000:-----:-----:13: SUBA.L s[Areg,Dreg],Ar
1001 rrr1 11ss sSSS:000:-----:-----:--:13: SUBA.L s[Areg,Dreg],Ar
- 2 0 2
1001 rrr1 11ss sSSS:000:-----:-----:13: SUBA.L s[!Areg,Dreg],Ar
1001 rrr1 11ss sSSS:000:-----:-----:--:13: SUBA.L s[!Areg,Dreg],Ar
- 0 0 2 fea
1011 rrr0 zzss sSSS:000:-NZVC:-----:11: CMP.z s[Areg,Dreg],Dr
1011 rrr0 zzss sSSS:000:-NZVC:-----:--:11: CMP.z s[Areg,Dreg],Dr
- 2 0 2
1011 rrr0 zzss sSSS:000:-NZVC:-----:11: CMP.z s[!Areg,Dreg],Dr
1011 rrr0 zzss sSSS:000:-NZVC:-----:--:11: CMP.z s[!Areg,Dreg],Dr
- 0 0 2 fea
1011 rrr0 11ss sSSS:000:-NZVC:-----:11: CMPA.W s[Areg,Dreg],Ar
1011 rrr0 11ss sSSS:000:-NZVC:-----:--:11: CMPA.W s[Areg,Dreg],Ar
- 4 0 4
1011 rrr0 11ss sSSS:000:-NZVC:-----:11: CMPA.W s[!Areg,Dreg],Ar
1011 rrr0 11ss sSSS:000:-NZVC:-----:--:11: CMPA.W s[!Areg,Dreg],Ar
- 0 0 4 fea
1011 rrr1 11ss sSSS:000:-NZVC:-----:11: CMPA.L s[Areg,Dreg],Ar
1011 rrr1 11ss sSSS:000:-NZVC:-----:--:11: CMPA.L s[Areg,Dreg],Ar
- 4 0 4
1011 rrr1 11ss sSSS:000:-NZVC:-----:11: CMPA.L s[!Areg,Dreg],Ar
1011 rrr1 11ss sSSS:000:-NZVC:-----:--:11: CMPA.L s[!Areg,Dreg],Ar
- 0 0 4 fea
1011 rrr1 zzdd dDDD:000:-NZVC:-----:11: CMPM.z d[Areg-Aipi],ArP
1011 rrr1 zzdd dDDD:000:-NZVC:-----:--:11: CMPM.z d[Areg-Aipi],ArP
- 0 0 8
1011 rrr1 zzdd dDDD:000:-NZ00:-----:13: EOR.z Dr,d[Dreg]
1011 rrr1 zzdd dDDD:000:-NZ00:-----:--:13: EOR.z Dr,d[Dreg]
- 2 0 2
1011 rrr1 zzdd dDDD:000:-NZ00:-----:13: EOR.z Dr,d[!Areg,Dreg]
1011 rrr1 zzdd dDDD:000:-NZ00:-----:--:13: EOR.z Dr,d[!Areg,Dreg]
- 0 1 3 fea
1100 rrr0 zzss sSSS:000:-NZ00:-----:13: AND.z s[Dreg],Dr
1100 rrr0 zzss sSSS:000:-NZ00:-----:--:13: AND.z s[Dreg],Dr
- 2 0 2 fea
1100 rrr0 zzss sSSS:000:-NZ00:-----:13: AND.z s[!Areg,Dreg],Dr
1100 rrr0 zzss sSSS:000:-NZ00:-----:--:13: AND.z s[!Areg,Dreg],Dr
- 0 1 3 fea
1100 rrr0 11ss sSSS:000:-NZ00:-----:13: MULU.W s[!Areg],Dr
1100 rrr0 11ss sSSS:000:-NZ00:-----:--:13: MULU.W s[!Areg],Dr
- 2 0 12 fea
1100 rrr1 00dd dDDD:000:XxZxC:X-Z--:13: ABCD.B d[Dreg],Dr
1100 rrr1 00dd dDDD:000:X?Z?C:X-Z--:--:13: ABCD.B d[Dreg],Dr
- 0 0 4
1100 rrr1 00dd dDDD:000:XxZxC:X-Z--:13: ABCD.B d[Areg-Apdi],Arp
1100 rrr1 00dd dDDD:000:X?Z?C:X-Z--:--:13: ABCD.B d[Areg-Apdi],Arp
- 2 1 13
1100 rrr1 zzdd dDDD:000:-NZ00:-----:13: AND.z Dr,d[!Areg,Dreg]
1100 rrr1 zzdd dDDD:000:-NZ00:-----:--:13: AND.z Dr,d[!Areg,Dreg]
- 0 1 3 fea
1100 rrr1 01dd dDDD:000:-----:-----:33: EXG.L Dr,d[Dreg]
1100 rrr1 01dd dDDD:000:-----:-----:--:33: EXG.L Dr,d[Dreg]
- 4 0 4
1100 rrr1 01dd dDDD:000:-----:-----:33: EXG.L Ar,d[Areg]
1100 rrr1 01dd dDDD:000:-----:-----:--:33: EXG.L Ar,d[Areg]
- 4 0 4
1100 rrr1 10dd dDDD:000:-----:-----:33: EXG.L Dr,d[Areg]
1100 rrr1 10dd dDDD:000:-----:-----:--:33: EXG.L Dr,d[Areg]
- 4 0 4
1100 rrr1 11ss sSSS:000:-NZ00:-----:13: MULS.W s[!Areg],Dr
1100 rrr1 11ss sSSS:000:-NZ00:-----:--:13: MULS.W s[!Areg],Dr
- 2 0 12 fea
1101 rrr0 zzss sSSS:000:XNZVC:-----:13: ADD.z s[Areg,Dreg],Dr
1101 rrr0 zzss sSSS:000:XNZVC:-----:--:13: ADD.z s[Areg,Dreg],Dr
- 2 0 2
1101 rrr0 zzss sSSS:000:XNZVC:-----:13: ADD.z s[!Areg,Dreg],Dr
1101 rrr0 zzss sSSS:000:XNZVC:-----:--:13: ADD.z s[!Areg,Dreg],Dr
- 0 0 2 fea
1101 rrr0 11ss sSSS:000:-----:-----:13: ADDA.W s[Areg,Dreg],Ar
1101 rrr0 11ss sSSS:000:-----:-----:--:13: ADDA.W s[Areg,Dreg],Ar
- 0 0 4
1101 rrr0 11ss sSSS:000:-----:-----:13: ADDA.W s[!Areg,Dreg],Ar
1101 rrr0 11ss sSSS:000:-----:-----:--:13: ADDA.W s[!Areg,Dreg],Ar
- 4 0 4 fea
1101 rrr1 zzdd dDDD:000:XNZVC:X-Z--:13: ADDX.z d[Dreg],Dr
1101 rrr1 zzdd dDDD:000:XNZVC:X-Z--:--:13: ADDX.z d[Dreg],Dr
- 2 0 2
1101 rrr1 zzdd dDDD:000:XNZVC:X-Z--:13: ADDX.z d[Areg-Apdi],Arp
1101 rrr1 zzdd dDDD:000:XNZVC:X-Z--:--:13: ADDX.z d[Areg-Apdi],Arp
- 2 1 9
1101 rrr1 zzdd dDDD:000:XNZVC:-----:13: ADD.z Dr,d[!Areg,Dreg]
1101 rrr1 zzdd dDDD:000:XNZVC:-----:--:13: ADD.z Dr,d[!Areg,Dreg]
- 0 1 3 fea
1101 rrr1 11ss sSSS:000:-----:-----:13: ADDA.L s[Areg,Dreg],Ar
1101 rrr1 11ss sSSS:000:-----:-----:--:13: ADDA.L s[Areg,Dreg],Ar
- 2 0 2
1101 rrr1 11ss sSSS:000:-----:-----:13: ADDA.L s[!Areg,Dreg],Ar
1101 rrr1 11ss sSSS:000:-----:-----:--:13: ADDA.L s[!Areg,Dreg],Ar
- 0 0 2 fea
1110 jjjf zz00 0RRR:000:XNZVC:-----:13: ASf.z #j,DR
1110 jjjf zz00 0RRR:000:XNZVC:-----:--:13: ASf.z #j,DR
- 2 0 6
1110 jjjf zz00 1RRR:000:XNZ0C:-----:13: LSf.z #j,DR
1110 jjjf zz00 1RRR:000:XNZ0C:-----:--:13: LSf.z #j,DR
- 4 0 4
1110 jjjf zz01 0RRR:000:XNZ0C:X----:13: ROXf.z #j,DR
1110 jjjf zz01 0RRR:000:XNZ0C:X----:--:13: ROXf.z #j,DR
- 10 0 12
1110 jjjf zz01 1RRR:000:-NZ0C:-----:13: ROf.z #j,DR
1110 jjjf zz01 1RRR:000:-NZ0C:-----:--:13: ROf.z #j,DR
- 4 0 6
1110 rrrf zz10 0RRR:000:XNZVC:X----:13: ASf.z Dr,DR
1110 rrrf zz10 0RRR:000:XNZVC:X----:--:13: ASf.z Dr,DR
- 4 0 6
1110 rrrf zz10 1RRR:000:XNZ0C:X----:13: LSf.z Dr,DR
1110 rrrf zz10 1RRR:000:XNZ0C:X----:--:13: LSf.z Dr,DR
- 6 0 6
1110 rrrf zz11 0RRR:000:XNZ0C:X----:13: ROXf.z Dr,DR
1110 rrrf zz11 0RRR:000:XNZ0C:X----:--:13: ROXf.z Dr,DR
- 10 0 12
1110 rrrf zz11 1RRR:000:-NZ0C:-----:13: ROf.z Dr,DR
1110 rrrf zz11 1RRR:000:-NZ0C:-----:--:13: ROf.z Dr,DR
- 6 0 8
1110 000f 11dd dDDD:000:XNZVC:-----:13: ASfW.W d[!Dreg,Areg]
1110 000f 11dd dDDD:000:XNZVC:-----:--:13: ASfW.W d[!Dreg,Areg]
- 0 0 4 fea
1110 001f 11dd dDDD:000:XNZ0C:-----:13: LSfW.W d[!Dreg,Areg]
1110 001f 11dd dDDD:000:XNZ0C:-----:--:13: LSfW.W d[!Dreg,Areg]
- 0 0 4 fea
1110 010f 11dd dDDD:000:XNZ0C:X----:13: ROXfW.W d[!Dreg,Areg]
1110 010f 11dd dDDD:000:XNZ0C:X----:--:13: ROXfW.W d[!Dreg,Areg]
- 0 0 4 fea
1110 011f 11dd dDDD:000:-NZ0C:-----:13: ROfW.W d[!Dreg,Areg]
1110 011f 11dd dDDD:000:-NZ0C:-----:--:13: ROfW.W d[!Dreg,Areg]
- 0 0 6 fea
1110 1000 11ss sSSS:200:?????:?????:11: BFTST #1,s[!Areg,Apdi,Aipi,Immd]
1110 1001 11ss sSSS:200:?????:?????:11: BFEXTU #1,s[!Areg,Apdi,Aipi,Immd]
1110 1010 11ss sSSS:200:?????:?????:13: BFCHG #1,s[!Areg,Apdi,Aipi,Immd,PC8r,PC16]
1110 1011 11ss sSSS:200:?????:?????:11: BFEXTS #1,s[!Areg,Apdi,Aipi,Immd]
1110 1100 11ss sSSS:200:?????:?????:13: BFCLR #1,s[!Areg,Apdi,Aipi,Immd,PC8r,PC16]
1110 1101 11ss sSSS:200:?????:?????:11: BFFFO #1,s[!Areg,Apdi,Aipi,Immd]
1110 1110 11ss sSSS:200:?????:?????:13: BFSET #1,s[!Areg,Apdi,Aipi,Immd,PC8r,PC16]
1110 1111 11ss sSSS:200:?????:?????:13: BFINS #1,s[!Areg,Apdi,Aipi,Immd,PC8r,PC16]
1110 1000 11ss sSSS:200:-NZ00:-----:--:11: BFTST #1,s[!Areg,Apdi,Aipi,Immd]
1110 1001 11ss sSSS:200:-NZ00:-----:--:11: BFEXTU #1,s[!Areg,Apdi,Aipi,Immd]
1110 1010 11ss sSSS:200:-NZ00:-----:--:13: BFCHG #1,s[!Areg,Apdi,Aipi,Immd,PC8r,PC16]
1110 1011 11ss sSSS:200:-NZ00:-----:--:11: BFEXTS #1,s[!Areg,Apdi,Aipi,Immd]
1110 1100 11ss sSSS:200:-NZ00:-----:--:13: BFCLR #1,s[!Areg,Apdi,Aipi,Immd,PC8r,PC16]
1110 1101 11ss sSSS:200:-NZ00:-----:--:11: BFFFO #1,s[!Areg,Apdi,Aipi,Immd]
1110 1110 11ss sSSS:200:-NZ00:-----:--:13: BFSET #1,s[!Areg,Apdi,Aipi,Immd,PC8r,PC16]
1110 1111 11ss sSSS:200:-NZ00:-----:--:13: BFINS #1,s[!Areg,Apdi,Aipi,Immd,PC8r,PC16]
% floating point co processor
1111 0010 00ss sSSS:200:?????:?????:11: FPP #1,s
1111 0010 01ss sSSS:200:?????:?????:11: FDBcc #1,s[Areg-Dreg]
1111 0010 01ss sSSS:200:?????:?????:11: FScc #1,s[!Areg,Immd,PC8r,PC16]
1111 0010 0111 1010:200:?????:?????:10: FTRAPcc #1
1111 0010 0111 1011:200:?????:?????:10: FTRAPcc #2
1111 0010 0111 1100:200:?????:?????:00: FTRAPcc
1111 0010 10KK KKKK:200:?????:?????:11: FBcc #K,#1
1111 0010 11KK KKKK:200:?????:?????:11: FBcc #K,#2
1111 0011 00ss sSSS:202:?????:?????:20: FSAVE s[!Dreg,Areg,Aipi,Immd,PC8r,PC16]
1111 0011 01ss sSSS:202:?????:?????:10: FRESTORE s[!Dreg,Areg,Apdi,Immd]
1111 0010 00ss sSSS:200:-----:-----:--:11: FPP #1,s
1111 0010 01ss sSSS:200:-----:-----:-B:11: FDBcc #1,s[Areg-Dreg]
1111 0010 01ss sSSS:200:-----:-----:--:11: FScc #1,s[!Areg,Immd,PC8r,PC16]
1111 0010 0111 1010:200:-----:-----:T-:10: FTRAPcc #1
1111 0010 0111 1011:200:-----:-----:T-:10: FTRAPcc #2
1111 0010 0111 1100:200:-----:-----:T-:00: FTRAPcc
1111 0010 10KK KKKK:200:-----:-----:-B:11: FBcc #K,#1
1111 0010 11KK KKKK:200:-----:-----:-B:11: FBcc #K,#2
1111 0011 00ss sSSS:202:-----:-----:--:20: FSAVE s[!Dreg,Areg,Aipi,Immd,PC8r,PC16]
1111 0011 01ss sSSS:202:-----:-----:--:10: FRESTORE s[!Dreg,Areg,Apdi,Immd]
% 68030 MMU (allowed addressing modes not checked!)
1111 0000 00ss sSSS:342:?????:?????:11: MMUOP030 s[Dreg,Areg,Apdi,Aipi,Aind,Ad16,Ad8r,absl,absw],#1
1111 0000 00ss sSSS:342:-----:-----:T-:11: MMUOP030 s[Dreg,Areg,Apdi,Aipi,Aind,Ad16,Ad8r,absl,absw],#1
% 68040/68060 instructions
1111 0100 pp00 1rrr:402:-----:-----:02: CINVL #p,Ar
1111 0100 pp01 0rrr:402:-----:-----:02: CINVP #p,Ar
1111 0100 pp01 1rrr:402:-----:-----:00: CINVA #p
1111 0100 pp10 1rrr:402:-----:-----:02: CPUSHL #p,Ar
1111 0100 pp11 0rrr:402:-----:-----:02: CPUSHP #p,Ar
1111 0100 pp11 1rrr:402:-----:-----:00: CPUSHA #p
1111 0101 0000 0rrr:402:-----:-----:00: PFLUSHN Ara
1111 0101 0000 1rrr:402:-----:-----:00: PFLUSH Ara
1111 0101 0001 0rrr:402:-----:-----:00: PFLUSHAN Ara
1111 0101 0001 1rrr:402:-----:-----:00: PFLUSHA Ara
1111 0100 pp00 1rrr:402:-----:-----:T-:02: CINVL #p,Ar
1111 0100 pp01 0rrr:402:-----:-----:T-:02: CINVP #p,Ar
1111 0100 pp01 1rrr:402:-----:-----:T-:00: CINVA #p
1111 0100 pp10 1rrr:402:-----:-----:T-:02: CPUSHL #p,Ar
1111 0100 pp11 0rrr:402:-----:-----:T-:02: CPUSHP #p,Ar
1111 0100 pp11 1rrr:402:-----:-----:T-:00: CPUSHA #p
1111 0101 0000 0rrr:402:-----:-----:T-:00: PFLUSHN Ara
1111 0101 0000 1rrr:402:-----:-----:T-:00: PFLUSH Ara
1111 0101 0001 0rrr:402:-----:-----:T-:00: PFLUSHAN Ara
1111 0101 0001 1rrr:402:-----:-----:T-:00: PFLUSHA Ara
% 68040 only
1111 0101 0100 1rrr:452:-----:-----:00: PTESTW Ara
1111 0101 0110 1rrr:452:-----:-----:00: PTESTR Ara
1111 0101 0100 1rrr:452:-----:-----:T-:00: PTESTW Ara
1111 0101 0110 1rrr:452:-----:-----:T-:00: PTESTR Ara
% destination register number is encoded in the following word
1111 0110 0010 0rrr:400:-----:-----:12: MOVE16 ArP,AxP
1111 0110 00ss sSSS:400:-----:-----:12: MOVE16 s[Dreg-Aipi],L
1111 0110 00dd dDDD:400:-----:-----:12: MOVE16 L,d[Areg-Aipi]
1111 0110 00ss sSSS:400:-----:-----:12: MOVE16 s[Aind],L
1111 0110 00dd dDDD:400:-----:-----:12: MOVE16 L,d[Aipi-Aind]
1111 0110 0010 0rrr:400:-----:-----:--:12: MOVE16 ArP,AxP
1111 0110 00ss sSSS:400:-----:-----:--:12: MOVE16 s[Dreg-Aipi],Al
1111 0110 00dd dDDD:400:-----:-----:--:12: MOVE16 Al,d[Areg-Aipi]
1111 0110 00ss sSSS:400:-----:-----:--:12: MOVE16 s[Aind],Al
1111 0110 00dd dDDD:400:-----:-----:--:12: MOVE16 Al,d[Aipi-Aind]
% 68060
1111 1000 0000 0000:500:?????:?????:10: LPSTOP #1
1111 0101 1000 1rrr:502:-----:-----:00: PLPAW Ara
1111 0101 1100 1rrr:502:-----:-----:00: PLPAR Ara
1111 1000 0000 0000:500:XNZVC:-----:T-:10: LPSTOP #1
1111 0101 1000 1rrr:502:-----:-----:T-:00: PLPAW Ara
1111 0101 1100 1rrr:502:-----:-----:T-:00: PLPAR Ara
% "Debug Pipe Control Mode Commands"
0100 1010 1100 1000:502:?????:?????:00: HALT
0100 1010 1100 1100:500:?????:?????:00: PULSE
0100 1010 1100 1000:502:-----:-----:--:00: HALT
0100 1010 1100 1100:500:-----:-----:--:00: PULSE