char opcstr[256];
int bitpos[16];
int flagset[5], flaguse[5];
+ char cflow;
unsigned int bitmask,bitpattern;
int n_variable;
}
}
+ 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();
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;
return; // BSUN
fpu_op_illg (opcode, 0, false, regs.fpiar);
} else if (cc) {
- Exception (7);
+ Exception_cpu_oldpc(7, oldpc);
}
}
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;
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
static void returncycles(int cycles)
{
+ if (using_nocycles) {
+ out("return 0;\n");
+ return;
+ }
if (using_ce || using_ce020) {
#if 0
if (tail_ce020 == 0)
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++;
}
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++;
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)
{
/* 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:
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");
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;
}
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");
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)
{
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,
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);
}
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);
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;
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");
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");
}
break;
case i_TRAPV:
+ exception_oldpc();
sync_m68k_pc();
if (cpu_level == 0) {
// 68000 TRAPV is really weird
// 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();
} else {
fill_prefetch_next();
out("if (GET_VFLG()) {\n");
- out("Exception_cpu(7);\n");
+ exception_cpu("7");
write_return_cycles(0);
out("}\n");
}
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");
}
next_level_000();
break;
case i_DIVU:
+ exception_oldpc();
tail_ce020_done = true;
genamodedual(curi,
curi->smode, "srcreg", sz_word, "src", 1, 0,
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();
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,
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();
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();
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;
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) {
}
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");
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");
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
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:
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");
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");
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");
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");
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");
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");
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");
}
}
-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");
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)
};
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)
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;
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) {
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);
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;
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");
if (freopen(fname, "wb", stdout) == NULL) {
abort();
}
+ generate_macros(stdout);
using_exception_3 = 1;
using_bus_error = 1;
using_simple_cycles = 0;
using_indirect = 1;
cpu_generic = false;
+ need_exception_oldpc = 0;
cpu_level = 0;
using_prefetch = 1;
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;
} 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++)
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) {
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);
#include "uae/types.h"
+#ifndef D
+#define D
+#endif
+#ifndef bug
+#define bug write_log
+#endif
+
#ifdef DEBUGGER
#define MAX_HIST 500
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
flagtype t0;
flagtype s;
flagtype m;
- flagtype x;
flagtype stopped;
int halted;
int exception;
#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);
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);
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);
#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)
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 {
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
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);
#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)
#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
--- /dev/null
+#include "options.h"
+#include "../memory.h"
#define CLOBBER_BT clobber_flags()
#define CLOBBER_BSF clobber_flags()
-/* The older code generator is now deprecated. */
-#define USE_NEW_RTASM 1
-
-#if USE_NEW_RTASM
-
#if defined(CPU_x86_64)
#define X86_TARGET_64BIT 1
/* The address override prefix causes a 5 cycles penalty on Intel Core
#define compemu_raw_jmp_r(a) raw_jmp_r(a)
#define compemu_raw_jnz(a) raw_jnz(a)
#define compemu_raw_jz_b_oponly() raw_jz_b_oponly()
+#define compemu_raw_jnz_b_oponly() raw_jnz_b_oponly()
#define compemu_raw_lea_l_brr(a,b,c) raw_lea_l_brr(a,b,c)
#define compemu_raw_lea_l_brr_indexed(a,b,c,d,e) raw_lea_l_brr_indexed(a,b,c,d,e)
#define compemu_raw_mov_b_mr(a,b) raw_mov_b_mr(a,b)
PUSHLr(r);
#endif
}
-LENDFUNC(NONE,WRITE,1,raw_push_l_r,(R4 r))
LOWFUNC(NONE,READ,1,raw_pop_l_r,(R4 r))
{
POPLr(r);
#endif
}
-LENDFUNC(NONE,READ,1,raw_pop_l_r,(R4 r))
LOWFUNC(NONE,READ,1,raw_pop_l_m,(MEMW d))
{
POPLm(d, X86_NOREG, X86_NOREG, 1);
#endif
}
-LENDFUNC(NONE,READ,1,raw_pop_l_m,(MEMW d))
LOWFUNC(WRITE,NONE,2,raw_bt_l_ri,(R4 r, IMM i))
{
BTLir(i, r);
}
-LENDFUNC(WRITE,NONE,2,raw_bt_l_ri,(R4 r, IMM i))
LOWFUNC(WRITE,NONE,2,raw_bt_l_rr,(R4 r, R4 b))
{
BTLrr(b, r);
}
-LENDFUNC(WRITE,NONE,2,raw_bt_l_rr,(R4 r, R4 b))
LOWFUNC(WRITE,NONE,2,raw_btc_l_ri,(RW4 r, IMM i))
{
BTCLir(i, r);
}
-LENDFUNC(WRITE,NONE,2,raw_btc_l_ri,(RW4 r, IMM i))
LOWFUNC(WRITE,NONE,2,raw_btc_l_rr,(RW4 r, R4 b))
{
BTCLrr(b, r);
}
-LENDFUNC(WRITE,NONE,2,raw_btc_l_rr,(RW4 r, R4 b))
LOWFUNC(WRITE,NONE,2,raw_btr_l_ri,(RW4 r, IMM i))
{
BTRLir(i, r);
}
-LENDFUNC(WRITE,NONE,2,raw_btr_l_ri,(RW4 r, IMM i))
LOWFUNC(WRITE,NONE,2,raw_btr_l_rr,(RW4 r, R4 b))
{
BTRLrr(b, r);
}
-LENDFUNC(WRITE,NONE,2,raw_btr_l_rr,(RW4 r, R4 b))
LOWFUNC(WRITE,NONE,2,raw_bts_l_ri,(RW4 r, IMM i))
{
BTSLir(i, r);
}
-LENDFUNC(WRITE,NONE,2,raw_bts_l_ri,(RW4 r, IMM i))
LOWFUNC(WRITE,NONE,2,raw_bts_l_rr,(RW4 r, R4 b))
{
BTSLrr(b, r);
}
-LENDFUNC(WRITE,NONE,2,raw_bts_l_rr,(RW4 r, R4 b))
LOWFUNC(WRITE,NONE,2,raw_sub_w_ri,(RW2 d, IMM i))
{
SUBWir(i, d);
}
-LENDFUNC(WRITE,NONE,2,raw_sub_w_ri,(RW2 d, IMM i))
LOWFUNC(NONE,READ,2,raw_mov_l_rm,(W4 d, MEMR s))
{
ADDR32 MOVLmr(s, X86_NOREG, X86_NOREG, 1, d);
}
-LENDFUNC(NONE,READ,2,raw_mov_l_rm,(W4 d, MEMR s))
LOWFUNC(NONE,WRITE,2,raw_mov_l_mi,(MEMW d, IMM s))
{
ADDR32 MOVLim(s, d, X86_NOREG, X86_NOREG, 1);
}
-LENDFUNC(NONE,WRITE,2,raw_mov_l_mi,(MEMW d, IMM s))
LOWFUNC(NONE,WRITE,2,raw_mov_w_mi,(MEMW d, IMM s))
{
ADDR32 MOVWim(s, d, X86_NOREG, X86_NOREG, 1);
}
-LENDFUNC(NONE,WRITE,2,raw_mov_w_mi,(MEMW d, IMM s))
LOWFUNC(NONE,WRITE,2,raw_mov_b_mi,(MEMW d, IMM s))
{
ADDR32 MOVBim(s, d, X86_NOREG, X86_NOREG, 1);
}
-LENDFUNC(NONE,WRITE,2,raw_mov_b_mi,(MEMW d, IMM s))
LOWFUNC(WRITE,RMW,2,raw_rol_b_mi,(MEMRW d, IMM i))
{
ADDR32 ROLBim(i, d, X86_NOREG, X86_NOREG, 1);
}
-LENDFUNC(WRITE,RMW,2,raw_rol_b_mi,(MEMRW d, IMM i))
LOWFUNC(WRITE,NONE,2,raw_rol_b_ri,(RW1 r, IMM i))
{
ROLBir(i, r);
}
-LENDFUNC(WRITE,NONE,2,raw_rol_b_ri,(RW1 r, IMM i))
LOWFUNC(WRITE,NONE,2,raw_rol_w_ri,(RW2 r, IMM i))
{
ROLWir(i, r);
}
-LENDFUNC(WRITE,NONE,2,raw_rol_w_ri,(RW2 r, IMM i))
LOWFUNC(WRITE,NONE,2,raw_rol_l_ri,(RW4 r, IMM i))
{
ROLLir(i, r);
}
-LENDFUNC(WRITE,NONE,2,raw_rol_l_ri,(RW4 r, IMM i))
LOWFUNC(WRITE,NONE,2,raw_rol_l_rr,(RW4 d, R1 r))
{
ROLLrr(r, d);
}
-LENDFUNC(WRITE,NONE,2,raw_rol_l_rr,(RW4 d, R1 r))
LOWFUNC(WRITE,NONE,2,raw_rol_w_rr,(RW2 d, R1 r))
{
ROLWrr(r, d);
}
-LENDFUNC(WRITE,NONE,2,raw_rol_w_rr,(RW2 d, R1 r))
LOWFUNC(WRITE,NONE,2,raw_rol_b_rr,(RW1 d, R1 r))
{
ROLBrr(r, d);
}
-LENDFUNC(WRITE,NONE,2,raw_rol_b_rr,(RW1 d, R1 r))
LOWFUNC(WRITE,NONE,2,raw_shll_l_rr,(RW4 d, R1 r))
{
SHLLrr(r, d);
}
-LENDFUNC(WRITE,NONE,2,raw_shll_l_rr,(RW4 d, R1 r))
LOWFUNC(WRITE,NONE,2,raw_shll_w_rr,(RW2 d, R1 r))
{
SHLWrr(r, d);
}
-LENDFUNC(WRITE,NONE,2,raw_shll_w_rr,(RW2 d, R1 r))
LOWFUNC(WRITE,NONE,2,raw_shll_b_rr,(RW1 d, R1 r))
{
SHLBrr(r, d);
}
-LENDFUNC(WRITE,NONE,2,raw_shll_b_rr,(RW1 d, R1 r))
LOWFUNC(WRITE,NONE,2,raw_ror_b_ri,(RW1 r, IMM i))
{
RORBir(i, r);
}
-LENDFUNC(WRITE,NONE,2,raw_ror_b_ri,(RW1 r, IMM i))
LOWFUNC(WRITE,NONE,2,raw_ror_w_ri,(RW2 r, IMM i))
{
RORWir(i, r);
}
-LENDFUNC(WRITE,NONE,2,raw_ror_w_ri,(RW2 r, IMM i))
LOWFUNC(WRITE,READ,2,raw_or_l_rm,(RW4 d, MEMR s))
{
ADDR32 ORLmr(s, X86_NOREG, X86_NOREG, 1, d);
}
-LENDFUNC(WRITE,READ,2,raw_or_l_rm,(RW4 d, MEMR s))
LOWFUNC(WRITE,NONE,2,raw_ror_l_ri,(RW4 r, IMM i))
{
RORLir(i, r);
}
-LENDFUNC(WRITE,NONE,2,raw_ror_l_ri,(RW4 r, IMM i))
LOWFUNC(WRITE,NONE,2,raw_ror_l_rr,(RW4 d, R1 r))
{
RORLrr(r, d);
}
-LENDFUNC(WRITE,NONE,2,raw_ror_l_rr,(RW4 d, R1 r))
LOWFUNC(WRITE,NONE,2,raw_ror_w_rr,(RW2 d, R1 r))
{
RORWrr(r, d);
}
-LENDFUNC(WRITE,NONE,2,raw_ror_w_rr,(RW2 d, R1 r))
LOWFUNC(WRITE,NONE,2,raw_ror_b_rr,(RW1 d, R1 r))
{
RORBrr(r, d);
}
-LENDFUNC(WRITE,NONE,2,raw_ror_b_rr,(RW1 d, R1 r))
LOWFUNC(WRITE,NONE,2,raw_shrl_l_rr,(RW4 d, R1 r))
{
SHRLrr(r, d);
}
-LENDFUNC(WRITE,NONE,2,raw_shrl_l_rr,(RW4 d, R1 r))
LOWFUNC(WRITE,NONE,2,raw_shrl_w_rr,(RW2 d, R1 r))
{
SHRWrr(r, d);
}
-LENDFUNC(WRITE,NONE,2,raw_shrl_w_rr,(RW2 d, R1 r))
LOWFUNC(WRITE,NONE,2,raw_shrl_b_rr,(RW1 d, R1 r))
{
SHRBrr(r, d);
}
-LENDFUNC(WRITE,NONE,2,raw_shrl_b_rr,(RW1 d, R1 r))
LOWFUNC(WRITE,NONE,2,raw_shra_l_rr,(RW4 d, R1 r))
{
SARLrr(r, d);
}
-LENDFUNC(WRITE,NONE,2,raw_shra_l_rr,(RW4 d, R1 r))
LOWFUNC(WRITE,NONE,2,raw_shra_w_rr,(RW2 d, R1 r))
{
SARWrr(r, d);
}
-LENDFUNC(WRITE,NONE,2,raw_shra_w_rr,(RW2 d, R1 r))
LOWFUNC(WRITE,NONE,2,raw_shra_b_rr,(RW1 d, R1 r))
{
SARBrr(r, d);
}
-LENDFUNC(WRITE,NONE,2,raw_shra_b_rr,(RW1 d, R1 r))
LOWFUNC(WRITE,NONE,2,raw_shll_l_ri,(RW4 r, IMM i))
{
SHLLir(i, r);
}
-LENDFUNC(WRITE,NONE,2,raw_shll_l_ri,(RW4 r, IMM i))
LOWFUNC(WRITE,NONE,2,raw_shll_w_ri,(RW2 r, IMM i))
{
SHLWir(i, r);
}
-LENDFUNC(WRITE,NONE,2,raw_shll_w_ri,(RW2 r, IMM i))
LOWFUNC(WRITE,NONE,2,raw_shll_b_ri,(RW1 r, IMM i))
{
SHLBir(i, r);
}
-LENDFUNC(WRITE,NONE,2,raw_shll_b_ri,(RW1 r, IMM i))
LOWFUNC(WRITE,NONE,2,raw_shrl_l_ri,(RW4 r, IMM i))
{
SHRLir(i, r);
}
-LENDFUNC(WRITE,NONE,2,raw_shrl_l_ri,(RW4 r, IMM i))
LOWFUNC(WRITE,NONE,2,raw_shrl_w_ri,(RW2 r, IMM i))
{
SHRWir(i, r);
}
-LENDFUNC(WRITE,NONE,2,raw_shrl_w_ri,(RW2 r, IMM i))
LOWFUNC(WRITE,NONE,2,raw_shrl_b_ri,(RW1 r, IMM i))
{
SHRBir(i, r);
}
-LENDFUNC(WRITE,NONE,2,raw_shrl_b_ri,(RW1 r, IMM i))
LOWFUNC(WRITE,NONE,2,raw_shra_l_ri,(RW4 r, IMM i))
{
SARLir(i, r);
}
-LENDFUNC(WRITE,NONE,2,raw_shra_l_ri,(RW4 r, IMM i))
LOWFUNC(WRITE,NONE,2,raw_shra_w_ri,(RW2 r, IMM i))
{
SARWir(i, r);
}
-LENDFUNC(WRITE,NONE,2,raw_shra_w_ri,(RW2 r, IMM i))
LOWFUNC(WRITE,NONE,2,raw_shra_b_ri,(RW1 r, IMM i))
{
SARBir(i, r);
}
-LENDFUNC(WRITE,NONE,2,raw_shra_b_ri,(RW1 r, IMM i))
LOWFUNC(WRITE,NONE,1,raw_sahf,(R2))
{
SAHF();
}
-LENDFUNC(WRITE,NONE,1,raw_sahf,(R2 dummy_ah))
LOWFUNC(NONE,NONE,1,raw_cpuid,(R4))
{
CPUID();
}
-LENDFUNC(NONE,NONE,1,raw_cpuid,(R4 dummy_eax))
LOWFUNC(READ,NONE,1,raw_lahf,(W2))
{
LAHF();
}
-LENDFUNC(READ,NONE,1,raw_lahf,(W2 dummy_ah))
LOWFUNC(READ,NONE,2,raw_setcc,(W1 d, IMM cc))
{
SETCCir(cc, d);
}
-LENDFUNC(READ,NONE,2,raw_setcc,(W1 d, IMM cc))
LOWFUNC(READ,WRITE,2,raw_setcc_m,(MEMW d, IMM cc))
{
ADDR32 SETCCim(cc, d, X86_NOREG, X86_NOREG, 1);
}
-LENDFUNC(READ,WRITE,2,raw_setcc_m,(MEMW d, IMM cc))
LOWFUNC(READ,NONE,3,raw_cmov_l_rr,(RW4 d, R4 s, IMM cc))
{
*target_p = (uintptr)x86_get_target() - ((uintptr)target_p + 1);
}
}
-LENDFUNC(READ,NONE,3,raw_cmov_l_rr,(RW4 d, R4 s, IMM cc))
LOWFUNC(WRITE,NONE,2,raw_bsf_l_rr,(W4 d, R4 s))
{
BSFLrr(s, d);
}
-LENDFUNC(WRITE,NONE,2,raw_bsf_l_rr,(W4 d, R4 s))
LOWFUNC(NONE,NONE,2,raw_sign_extend_32_rr,(W4 d, R4 s))
{
MOVSLQrr(s, d);
}
-LENDFUNC(NONE,NONE,2,raw_sign_extend_32_rr,(W4 d, R4 s))
LOWFUNC(NONE,NONE,2,raw_sign_extend_16_rr,(W4 d, R2 s))
{
MOVSWLrr(s, d);
}
-LENDFUNC(NONE,NONE,2,raw_sign_extend_16_rr,(W4 d, R2 s))
LOWFUNC(NONE,NONE,2,raw_sign_extend_8_rr,(W4 d, R1 s))
{
MOVSBLrr(s, d);
}
-LENDFUNC(NONE,NONE,2,raw_sign_extend_8_rr,(W4 d, R1 s))
LOWFUNC(NONE,NONE,2,raw_zero_extend_16_rr,(W4 d, R2 s))
{
MOVZWLrr(s, d);
}
-LENDFUNC(NONE,NONE,2,raw_zero_extend_16_rr,(W4 d, R2 s))
LOWFUNC(NONE,NONE,2,raw_zero_extend_8_rr,(W4 d, R1 s))
{
MOVZBLrr(s, d);
}
-LENDFUNC(NONE,NONE,2,raw_zero_extend_8_rr,(W4 d, R1 s))
LOWFUNC(NONE,NONE,2,raw_imul_32_32,(RW4 d, R4 s))
{
IMULLrr(s, d);
}
-LENDFUNC(NONE,NONE,2,raw_imul_32_32,(RW4 d, R4 s))
LOWFUNC(NONE,NONE,2,raw_imul_64_32,(RW4 d, RW4 s))
{
}
IMULLr(s);
}
-LENDFUNC(NONE,NONE,2,raw_imul_64_32,(RW4 d, RW4 s))
LOWFUNC(NONE,NONE,2,raw_mul_64_32,(RW4 d, RW4 s))
{
}
MULLr(s);
}
-LENDFUNC(NONE,NONE,2,raw_mul_64_32,(RW4 d, RW4 s))
LOWFUNC(NONE,NONE,2,raw_mul_32_32,(RW4, R4))
{
- abort(); /* %^$&%^$%#^ x86! */
+ x86_emit_failure("raw_mul_32_32"); /* %^$&%^$%#^ x86! */
}
-LENDFUNC(NONE,NONE,2,raw_mul_32_32,(RW4 d, R4 s))
LOWFUNC(NONE,NONE,2,raw_mov_b_rr,(W1 d, R1 s))
{
MOVBrr(s, d);
}
-LENDFUNC(NONE,NONE,2,raw_mov_b_rr,(W1 d, R1 s))
LOWFUNC(NONE,NONE,2,raw_mov_w_rr,(W2 d, R2 s))
{
MOVWrr(s, d);
}
-LENDFUNC(NONE,NONE,2,raw_mov_w_rr,(W2 d, R2 s))
LOWFUNC(NONE,READ,4,raw_mov_l_rrm_indexed,(W4 d,R4 baser, R4 index, IMM factor))
{
ADDR32 MOVLmr(0, baser, index, factor, d);
}
-LENDFUNC(NONE,READ,4,raw_mov_l_rrm_indexed,(W4 d,R4 baser, R4 index, IMM factor))
LOWFUNC(NONE,READ,4,raw_mov_w_rrm_indexed,(W2 d, R4 baser, R4 index, IMM factor))
{
ADDR32 MOVWmr(0, baser, index, factor, d);
}
-LENDFUNC(NONE,READ,4,raw_mov_w_rrm_indexed,(W2 d, R4 baser, R4 index, IMM factor))
LOWFUNC(NONE,READ,4,raw_mov_b_rrm_indexed,(W1 d, R4 baser, R4 index, IMM factor))
{
ADDR32 MOVBmr(0, baser, index, factor, d);
}
-LENDFUNC(NONE,READ,4,raw_mov_b_rrm_indexed,(W1 d, R4 baser, R4 index, IMM factor))
LOWFUNC(NONE,WRITE,4,raw_mov_l_mrr_indexed,(R4 baser, R4 index, IMM factor, R4 s))
{
ADDR32 MOVLrm(s, 0, baser, index, factor);
}
-LENDFUNC(NONE,WRITE,4,raw_mov_l_mrr_indexed,(R4 baser, R4 index, IMM factor, R4 s))
LOWFUNC(NONE,WRITE,4,raw_mov_w_mrr_indexed,(R4 baser, R4 index, IMM factor, R2 s))
{
ADDR32 MOVWrm(s, 0, baser, index, factor);
}
-LENDFUNC(NONE,WRITE,4,raw_mov_w_mrr_indexed,(R4 baser, R4 index, IMM factor, R2 s))
LOWFUNC(NONE,WRITE,4,raw_mov_b_mrr_indexed,(R4 baser, R4 index, IMM factor, R1 s))
{
ADDR32 MOVBrm(s, 0, baser, index, factor);
}
-LENDFUNC(NONE,WRITE,4,raw_mov_b_mrr_indexed,(R4 baser, R4 index, IMM factor, R1 s))
LOWFUNC(NONE,WRITE,5,raw_mov_l_bmrr_indexed,(IMM base, R4 baser, R4 index, IMM factor, R4 s))
{
ADDR32 MOVLrm(s, base, baser, index, factor);
}
-LENDFUNC(NONE,WRITE,5,raw_mov_l_bmrr_indexed,(IMM base, R4 baser, R4 index, IMM factor, R4 s))
LOWFUNC(NONE,WRITE,5,raw_mov_w_bmrr_indexed,(IMM base, R4 baser, R4 index, IMM factor, R2 s))
{
ADDR32 MOVWrm(s, base, baser, index, factor);
}
-LENDFUNC(NONE,WRITE,5,raw_mov_w_bmrr_indexed,(IMM base, R4 baser, R4 index, IMM factor, R2 s))
LOWFUNC(NONE,WRITE,5,raw_mov_b_bmrr_indexed,(IMM base, R4 baser, R4 index, IMM factor, R1 s))
{
ADDR32 MOVBrm(s, base, baser, index, factor);
}
-LENDFUNC(NONE,WRITE,5,raw_mov_b_bmrr_indexed,(IMM base, R4 baser, R4 index, IMM factor, R1 s))
LOWFUNC(NONE,READ,5,raw_mov_l_brrm_indexed,(W4 d, IMM base, R4 baser, R4 index, IMM factor))
{
ADDR32 MOVLmr(base, baser, index, factor, d);
}
-LENDFUNC(NONE,READ,5,raw_mov_l_brrm_indexed,(W4 d, IMM base, R4 baser, R4 index, IMM factor))
LOWFUNC(NONE,READ,5,raw_mov_w_brrm_indexed,(W2 d, IMM base, R4 baser, R4 index, IMM factor))
{
ADDR32 MOVWmr(base, baser, index, factor, d);
}
-LENDFUNC(NONE,READ,5,raw_mov_w_brrm_indexed,(W2 d, IMM base, R4 baser, R4 index, IMM factor))
LOWFUNC(NONE,READ,5,raw_mov_b_brrm_indexed,(W1 d, IMM base, R4 baser, R4 index, IMM factor))
{
ADDR32 MOVBmr(base, baser, index, factor, d);
}
-LENDFUNC(NONE,READ,5,raw_mov_b_brrm_indexed,(W1 d, IMM base, R4 baser, R4 index, IMM factor))
LOWFUNC(NONE,READ,4,raw_mov_l_rm_indexed,(W4 d, IMM base, R4 index, IMM factor))
{
ADDR32 MOVLmr(base, X86_NOREG, index, factor, d);
}
-LENDFUNC(NONE,READ,4,raw_mov_l_rm_indexed,(W4 d, IMM base, R4 index, IMM factor))
LOWFUNC(NONE,READ,5,raw_cmov_l_rm_indexed,(W4 d, IMM base, R4 index, IMM factor, IMM cond))
{
*target_p = (uintptr)x86_get_target() - ((uintptr)target_p + 1);
}
}
-LENDFUNC(NONE,READ,5,raw_cmov_l_rm_indexed,(W4 d, IMM base, R4 index, IMM factor, IMM cond))
LOWFUNC(NONE,READ,3,raw_cmov_l_rm,(W4 d, IMM mem, IMM cond))
{
*target_p = (uintptr)x86_get_target() - ((uintptr)target_p + 1);
}
}
-LENDFUNC(NONE,READ,3,raw_cmov_l_rm,(W4 d, IMM mem, IMM cond))
LOWFUNC(NONE,READ,3,raw_mov_l_rR,(W4 d, R4 s, IMM offset))
{
ADDR32 MOVLmr(offset, s, X86_NOREG, 1, d);
}
-LENDFUNC(NONE,READ,3,raw_mov_l_rR,(W4 d, R4 s, IMM offset))
LOWFUNC(NONE,READ,3,raw_mov_w_rR,(W2 d, R4 s, IMM offset))
{
ADDR32 MOVWmr(offset, s, X86_NOREG, 1, d);
}
-LENDFUNC(NONE,READ,3,raw_mov_w_rR,(W2 d, R4 s, IMM offset))
LOWFUNC(NONE,READ,3,raw_mov_b_rR,(W1 d, R4 s, IMM offset))
{
ADDR32 MOVBmr(offset, s, X86_NOREG, 1, d);
}
-LENDFUNC(NONE,READ,3,raw_mov_b_rR,(W1 d, R4 s, IMM offset))
LOWFUNC(NONE,READ,3,raw_mov_l_brR,(W4 d, R4 s, IMM offset))
{
ADDR32 MOVLmr(offset, s, X86_NOREG, 1, d);
}
-LENDFUNC(NONE,READ,3,raw_mov_l_brR,(W4 d, R4 s, IMM offset))
LOWFUNC(NONE,READ,3,raw_mov_w_brR,(W2 d, R4 s, IMM offset))
{
ADDR32 MOVWmr(offset, s, X86_NOREG, 1, d);
}
-LENDFUNC(NONE,READ,3,raw_mov_w_brR,(W2 d, R4 s, IMM offset))
LOWFUNC(NONE,READ,3,raw_mov_b_brR,(W1 d, R4 s, IMM offset))
{
ADDR32 MOVBmr(offset, s, X86_NOREG, 1, d);
}
-LENDFUNC(NONE,READ,3,raw_mov_b_brR,(W1 d, R4 s, IMM offset))
LOWFUNC(NONE,WRITE,3,raw_mov_l_Ri,(R4 d, IMM i, IMM offset))
{
ADDR32 MOVLim(i, offset, d, X86_NOREG, 1);
}
-LENDFUNC(NONE,WRITE,3,raw_mov_l_Ri,(R4 d, IMM i, IMM offset))
LOWFUNC(NONE,WRITE,3,raw_mov_w_Ri,(R4 d, IMM i, IMM offset))
{
ADDR32 MOVWim(i, offset, d, X86_NOREG, 1);
}
-LENDFUNC(NONE,WRITE,3,raw_mov_w_Ri,(R4 d, IMM i, IMM offset))
LOWFUNC(NONE,WRITE,3,raw_mov_b_Ri,(R4 d, IMM i, IMM offset))
{
ADDR32 MOVBim(i, offset, d, X86_NOREG, 1);
}
-LENDFUNC(NONE,WRITE,3,raw_mov_b_Ri,(R4 d, IMM i, IMM offset))
LOWFUNC(NONE,WRITE,3,raw_mov_l_Rr,(R4 d, R4 s, IMM offset))
{
ADDR32 MOVLrm(s, offset, d, X86_NOREG, 1);
}
-LENDFUNC(NONE,WRITE,3,raw_mov_l_Rr,(R4 d, R4 s, IMM offset))
LOWFUNC(NONE,WRITE,3,raw_mov_w_Rr,(R4 d, R2 s, IMM offset))
{
ADDR32 MOVWrm(s, offset, d, X86_NOREG, 1);
}
-LENDFUNC(NONE,WRITE,3,raw_mov_w_Rr,(R4 d, R2 s, IMM offset))
LOWFUNC(NONE,WRITE,3,raw_mov_b_Rr,(R4 d, R1 s, IMM offset))
{
ADDR32 MOVBrm(s, offset, d, X86_NOREG, 1);
}
-LENDFUNC(NONE,WRITE,3,raw_mov_b_Rr,(R4 d, R1 s, IMM offset))
LOWFUNC(NONE,NONE,3,raw_lea_l_brr,(W4 d, R4 s, IMM offset))
{
ADDR32 LEALmr(offset, s, X86_NOREG, 1, d);
}
-LENDFUNC(NONE,NONE,3,raw_lea_l_brr,(W4 d, R4 s, IMM offset))
LOWFUNC(NONE,NONE,5,raw_lea_l_brr_indexed,(W4 d, R4 s, R4 index, IMM factor, IMM offset))
{
ADDR32 LEALmr(offset, s, index, factor, d);
}
-LENDFUNC(NONE,NONE,5,raw_lea_l_brr_indexed,(W4 d, R4 s, R4 index, IMM factor, IMM offset))
LOWFUNC(NONE,NONE,4,raw_lea_l_rr_indexed,(W4 d, R4 s, R4 index, IMM factor))
{
ADDR32 LEALmr(0, s, index, factor, d);
}
-LENDFUNC(NONE,NONE,4,raw_lea_l_rr_indexed,(W4 d, R4 s, R4 index, IMM factor))
LOWFUNC(NONE,NONE,4,raw_lea_l_r_scaled,(W4 d, R4 index, IMM factor))
{
ADDR32 LEALmr(0, X86_NOREG, index, factor, d);
}
-LENDFUNC(NONE,NONE,4,raw_lea_l_r_scaled,(W4 d, R4 index, IMM factor))
LOWFUNC(NONE,WRITE,3,raw_mov_l_bRr,(R4 d, R4 s, IMM offset))
-{
- ADDR32 MOVLrm(s, offset, d, X86_NOREG, 1);
-}
-LENDFUNC(NONE,WRITE,3,raw_mov_l_bRr,(R4 d, R4 s, IMM offset))
-
-LOWFUNC(NONE,WRITE,3,raw_mov_w_bRr,(R4 d, R2 s, IMM offset))
-{
- ADDR32 MOVWrm(s, offset, d, X86_NOREG, 1);
-}
-LENDFUNC(NONE,WRITE,3,raw_mov_w_bRr,(R4 d, R2 s, IMM offset))
-
-LOWFUNC(NONE,WRITE,3,raw_mov_b_bRr,(R4 d, R1 s, IMM offset))
-{
- ADDR32 MOVBrm(s, offset, d, X86_NOREG, 1);
-}
-LENDFUNC(NONE,WRITE,3,raw_mov_b_bRr,(R4 d, R1 s, IMM offset))
-
-LOWFUNC(NONE,NONE,1,raw_bswap_32,(RW4 r))
-{
- BSWAPLr(r);
-}
-LENDFUNC(NONE,NONE,1,raw_bswap_32,(RW4 r))
-
-LOWFUNC(WRITE,NONE,1,raw_bswap_16,(RW2 r))
-{
- ROLWir(8, r);
-}
-LENDFUNC(WRITE,NONE,1,raw_bswap_16,(RW2 r))
-
-LOWFUNC(NONE,NONE,2,raw_mov_l_rr,(W4 d, R4 s))
-{
- MOVLrr(s, d);
-}
-LENDFUNC(NONE,NONE,2,raw_mov_l_rr,(W4 d, R4 s))
-
-LOWFUNC(NONE,WRITE,2,raw_mov_l_mr,(IMM d, R4 s))
-{
- ADDR32 MOVLrm(s, d, X86_NOREG, X86_NOREG, 1);
-}
-LENDFUNC(NONE,WRITE,2,raw_mov_l_mr,(IMM d, R4 s))
-
-LOWFUNC(NONE,WRITE,2,raw_mov_w_mr,(IMM d, R2 s))
-{
- ADDR32 MOVWrm(s, d, X86_NOREG, X86_NOREG, 1);
-}
-LENDFUNC(NONE,WRITE,2,raw_mov_w_mr,(IMM d, R2 s))
-
-LOWFUNC(NONE,READ,2,raw_mov_w_rm,(W2 d, IMM s))
-{
- ADDR32 MOVWmr(s, X86_NOREG, X86_NOREG, 1, d);
-}
-LENDFUNC(NONE,READ,2,raw_mov_w_rm,(W2 d, IMM s))
-
-LOWFUNC(NONE,WRITE,2,raw_mov_b_mr,(IMM d, R1 s))
-{
- ADDR32 MOVBrm(s, d, X86_NOREG, X86_NOREG, 1);
-}
-LENDFUNC(NONE,WRITE,2,raw_mov_b_mr,(IMM d, R1 s))
-
-LOWFUNC(NONE,READ,2,raw_mov_b_rm,(W1 d, IMM s))
-{
- ADDR32 MOVBmr(s, X86_NOREG, X86_NOREG, 1, d);
-}
-LENDFUNC(NONE,READ,2,raw_mov_b_rm,(W1 d, IMM s))
-
-LOWFUNC(NONE,NONE,2,raw_mov_l_ri,(W4 d, IMM s))
-{
- MOVLir(s, d);
-}
-LENDFUNC(NONE,NONE,2,raw_mov_l_ri,(W4 d, IMM s))
-
-LOWFUNC(NONE,NONE,2,raw_mov_w_ri,(W2 d, IMM s))
-{
- MOVWir(s, d);
-}
-LENDFUNC(NONE,NONE,2,raw_mov_w_ri,(W2 d, IMM s))
-
-LOWFUNC(NONE,NONE,2,raw_mov_b_ri,(W1 d, IMM s))
-{
- MOVBir(s, d);
-}
-LENDFUNC(NONE,NONE,2,raw_mov_b_ri,(W1 d, IMM s))
-
-LOWFUNC(RMW,RMW,2,raw_adc_l_mi,(MEMRW d, IMM s))
-{
- ADDR32 ADCLim(s, d, X86_NOREG, X86_NOREG, 1);
-}
-LENDFUNC(RMW,RMW,2,raw_adc_l_mi,(MEMRW d, IMM s))
-
-LOWFUNC(WRITE,RMW,2,raw_add_l_mi,(IMM d, IMM s))
-{
- ADDR32 ADDLim(s, d, X86_NOREG, X86_NOREG, 1);
-}
-LENDFUNC(WRITE,RMW,2,raw_add_l_mi,(IMM d, IMM s))
-
-LOWFUNC(WRITE,RMW,2,raw_add_w_mi,(IMM d, IMM s))
-{
- ADDR32 ADDWim(s, d, X86_NOREG, X86_NOREG, 1);
-}
-LENDFUNC(WRITE,RMW,2,raw_add_w_mi,(IMM d, IMM s))
-
-LOWFUNC(WRITE,RMW,2,raw_add_b_mi,(IMM d, IMM s))
-{
- ADDR32 ADDBim(s, d, X86_NOREG, X86_NOREG, 1);
-}
-LENDFUNC(WRITE,RMW,2,raw_add_b_mi,(IMM d, IMM s))
-
-LOWFUNC(WRITE,NONE,2,raw_test_l_ri,(R4 d, IMM i))
-{
- TESTLir(i, d);
-}
-LENDFUNC(WRITE,NONE,2,raw_test_l_ri,(R4 d, IMM i))
-
-LOWFUNC(WRITE,NONE,2,raw_test_l_rr,(R4 d, R4 s))
-{
- TESTLrr(s, d);
-}
-LENDFUNC(WRITE,NONE,2,raw_test_l_rr,(R4 d, R4 s))
-
-LOWFUNC(WRITE,NONE,2,raw_test_w_rr,(R2 d, R2 s))
-{
- TESTWrr(s, d);
-}
-LENDFUNC(WRITE,NONE,2,raw_test_w_rr,(R2 d, R2 s))
-
-LOWFUNC(WRITE,NONE,2,raw_test_b_rr,(R1 d, R1 s))
-{
- TESTBrr(s, d);
-}
-LENDFUNC(WRITE,NONE,2,raw_test_b_rr,(R1 d, R1 s))
-
-LOWFUNC(WRITE,NONE,2,raw_xor_l_ri,(RW4 d, IMM i))
-{
- XORLir(i, d);
-}
-LENDFUNC(WRITE,NONE,2,raw_xor_l_ri,(RW4 d, IMM i))
-
-LOWFUNC(WRITE,NONE,2,raw_and_l_ri,(RW4 d, IMM i))
-{
- ANDLir(i, d);
-}
-LENDFUNC(WRITE,NONE,2,raw_and_l_ri,(RW4 d, IMM i))
-
-LOWFUNC(WRITE,NONE,2,raw_and_w_ri,(RW2 d, IMM i))
-{
- ANDWir(i, d);
-}
-LENDFUNC(WRITE,NONE,2,raw_and_w_ri,(RW2 d, IMM i))
-
-LOWFUNC(WRITE,NONE,2,raw_and_l,(RW4 d, R4 s))
-{
- ANDLrr(s, d);
-}
-LENDFUNC(WRITE,NONE,2,raw_and_l,(RW4 d, R4 s))
-
-LOWFUNC(WRITE,NONE,2,raw_and_w,(RW2 d, R2 s))
-{
- ANDWrr(s, d);
-}
-LENDFUNC(WRITE,NONE,2,raw_and_w,(RW2 d, R2 s))
-
-LOWFUNC(WRITE,NONE,2,raw_and_b,(RW1 d, R1 s))
-{
- ANDBrr(s, d);
-}
-LENDFUNC(WRITE,NONE,2,raw_and_b,(RW1 d, R1 s))
-
-LOWFUNC(WRITE,NONE,2,raw_or_l_ri,(RW4 d, IMM i))
-{
- ORLir(i, d);
-}
-LENDFUNC(WRITE,NONE,2,raw_or_l_ri,(RW4 d, IMM i))
-
-LOWFUNC(WRITE,NONE,2,raw_or_l,(RW4 d, R4 s))
-{
- ORLrr(s, d);
-}
-LENDFUNC(WRITE,NONE,2,raw_or_l,(RW4 d, R4 s))
-
-LOWFUNC(WRITE,NONE,2,raw_or_w,(RW2 d, R2 s))
-{
- ORWrr(s, d);
-}
-LENDFUNC(WRITE,NONE,2,raw_or_w,(RW2 d, R2 s))
-
-LOWFUNC(WRITE,NONE,2,raw_or_b,(RW1 d, R1 s))
-{
- ORBrr(s, d);
-}
-LENDFUNC(WRITE,NONE,2,raw_or_b,(RW1 d, R1 s))
-
-LOWFUNC(RMW,NONE,2,raw_adc_l,(RW4 d, R4 s))
-{
- ADCLrr(s, d);
-}
-LENDFUNC(RMW,NONE,2,raw_adc_l,(RW4 d, R4 s))
-
-LOWFUNC(RMW,NONE,2,raw_adc_w,(RW2 d, R2 s))
-{
- ADCWrr(s, d);
-}
-LENDFUNC(RMW,NONE,2,raw_adc_w,(RW2 d, R2 s))
-
-LOWFUNC(RMW,NONE,2,raw_adc_b,(RW1 d, R1 s))
-{
- ADCBrr(s, d);
-}
-LENDFUNC(RMW,NONE,2,raw_adc_b,(RW1 d, R1 s))
-
-LOWFUNC(WRITE,NONE,2,raw_add_l,(RW4 d, R4 s))
-{
- ADDLrr(s, d);
-}
-LENDFUNC(WRITE,NONE,2,raw_add_l,(RW4 d, R4 s))
-
-LOWFUNC(WRITE,NONE,2,raw_add_w,(RW2 d, R2 s))
-{
- ADDWrr(s, d);
-}
-LENDFUNC(WRITE,NONE,2,raw_add_w,(RW2 d, R2 s))
-
-LOWFUNC(WRITE,NONE,2,raw_add_b,(RW1 d, R1 s))
-{
- ADDBrr(s, d);
-}
-LENDFUNC(WRITE,NONE,2,raw_add_b,(RW1 d, R1 s))
-
-LOWFUNC(WRITE,NONE,2,raw_sub_l_ri,(RW4 d, IMM i))
-{
- SUBLir(i, d);
-}
-LENDFUNC(WRITE,NONE,2,raw_sub_l_ri,(RW4 d, IMM i))
-
-LOWFUNC(WRITE,NONE,2,raw_sub_b_ri,(RW1 d, IMM i))
-{
- SUBBir(i, d);
-}
-LENDFUNC(WRITE,NONE,2,raw_sub_b_ri,(RW1 d, IMM i))
-
-LOWFUNC(WRITE,NONE,2,raw_add_l_ri,(RW4 d, IMM i))
-{
- ADDLir(i, d);
-}
-LENDFUNC(WRITE,NONE,2,raw_add_l_ri,(RW4 d, IMM i))
-
-LOWFUNC(WRITE,NONE,2,raw_add_w_ri,(RW2 d, IMM i))
-{
- ADDWir(i, d);
-}
-LENDFUNC(WRITE,NONE,2,raw_add_w_ri,(RW2 d, IMM i))
-
-LOWFUNC(WRITE,NONE,2,raw_add_b_ri,(RW1 d, IMM i))
-{
- ADDBir(i, d);
-}
-LENDFUNC(WRITE,NONE,2,raw_add_b_ri,(RW1 d, IMM i))
-
-LOWFUNC(RMW,NONE,2,raw_sbb_l,(RW4 d, R4 s))
-{
- SBBLrr(s, d);
-}
-LENDFUNC(RMW,NONE,2,raw_sbb_l,(RW4 d, R4 s))
-
-LOWFUNC(RMW,NONE,2,raw_sbb_w,(RW2 d, R2 s))
-{
- SBBWrr(s, d);
-}
-LENDFUNC(RMW,NONE,2,raw_sbb_w,(RW2 d, R2 s))
-
-LOWFUNC(RMW,NONE,2,raw_sbb_b,(RW1 d, R1 s))
-{
- SBBBrr(s, d);
-}
-LENDFUNC(RMW,NONE,2,raw_sbb_b,(RW1 d, R1 s))
-
-LOWFUNC(WRITE,NONE,2,raw_sub_l,(RW4 d, R4 s))
-{
- SUBLrr(s, d);
-}
-LENDFUNC(WRITE,NONE,2,raw_sub_l,(RW4 d, R4 s))
-
-LOWFUNC(WRITE,NONE,2,raw_sub_w,(RW2 d, R2 s))
-{
- SUBWrr(s, d);
-}
-LENDFUNC(WRITE,NONE,2,raw_sub_w,(RW2 d, R2 s))
-
-LOWFUNC(WRITE,NONE,2,raw_sub_b,(RW1 d, R1 s))
-{
- SUBBrr(s, d);
-}
-LENDFUNC(WRITE,NONE,2,raw_sub_b,(RW1 d, R1 s))
-
-LOWFUNC(WRITE,NONE,2,raw_cmp_l,(R4 d, R4 s))
-{
- CMPLrr(s, d);
-}
-LENDFUNC(WRITE,NONE,2,raw_cmp_l,(R4 d, R4 s))
-
-LOWFUNC(WRITE,NONE,2,raw_cmp_l_ri,(R4 r, IMM i))
-{
- CMPLir(i, r);
-}
-LENDFUNC(WRITE,NONE,2,raw_cmp_l_ri,(R4 r, IMM i))
-
-LOWFUNC(WRITE,NONE,2,raw_cmp_w,(R2 d, R2 s))
-{
- CMPWrr(s, d);
-}
-LENDFUNC(WRITE,NONE,2,raw_cmp_w,(R2 d, R2 s))
-
-LOWFUNC(WRITE,READ,2,raw_cmp_b_mi,(MEMR d, IMM s))
-{
- ADDR32 CMPBim(s, d, X86_NOREG, X86_NOREG, 1);
-}
-LENDFUNC(WRITE,READ,2,raw_cmp_b_mi,(MEMR d, IMM s))
-
-LOWFUNC(WRITE,NONE,2,raw_cmp_b_ri,(R1 d, IMM i))
-{
- CMPBir(i, d);
-}
-LENDFUNC(WRITE,NONE,2,raw_cmp_b_ri,(R1 d, IMM i))
-
-LOWFUNC(WRITE,NONE,2,raw_cmp_b,(R1 d, R1 s))
-{
- CMPBrr(s, d);
-}
-LENDFUNC(WRITE,NONE,2,raw_cmp_b,(R1 d, R1 s))
-
-LOWFUNC(WRITE,READ,4,raw_cmp_l_rm_indexed,(R4 d, IMM offset, R4 index, IMM factor))
-{
- ADDR32 CMPLmr(offset, X86_NOREG, index, factor, d);
-}
-LENDFUNC(WRITE,READ,4,raw_cmp_l_rm_indexed,(R4 d, IMM offset, R4 index, IMM factor))
-
-LOWFUNC(WRITE,NONE,2,raw_xor_l,(RW4 d, R4 s))
-{
- XORLrr(s, d);
-}
-LENDFUNC(WRITE,NONE,2,raw_xor_l,(RW4 d, R4 s))
-
-LOWFUNC(WRITE,NONE,2,raw_xor_w,(RW2 d, R2 s))
-{
- XORWrr(s, d);
-}
-LENDFUNC(WRITE,NONE,2,raw_xor_w,(RW2 d, R2 s))
-
-LOWFUNC(WRITE,NONE,2,raw_xor_b,(RW1 d, R1 s))
-{
- XORBrr(s, d);
-}
-LENDFUNC(WRITE,NONE,2,raw_xor_b,(RW1 d, R1 s))
-
-LOWFUNC(WRITE,RMW,2,raw_sub_l_mi,(MEMRW d, IMM s))
-{
- ADDR32 SUBLim(s, d, X86_NOREG, X86_NOREG, 1);
-}
-LENDFUNC(WRITE,RMW,2,raw_sub_l_mi,(MEMRW d, IMM s))
-
-LOWFUNC(WRITE,READ,2,raw_cmp_l_mi,(MEMR d, IMM s))
-{
- ADDR32 CMPLim(s, d, X86_NOREG, X86_NOREG, 1);
-}
-LENDFUNC(WRITE,READ,2,raw_cmp_l_mi,(MEMR d, IMM s))
-
-LOWFUNC(NONE,NONE,2,raw_xchg_l_rr,(RW4 r1, RW4 r2))
-{
- XCHGLrr(r2, r1);
-}
-LENDFUNC(NONE,NONE,2,raw_xchg_l_rr,(RW4 r1, RW4 r2))
-
-LOWFUNC(NONE,NONE,2,raw_xchg_b_rr,(RW4 r1, RW4 r2))
-{
- XCHGBrr(r2, r1);
-}
-LENDFUNC(NONE,NONE,2,raw_xchg_b_rr,(RW4 r1, RW4 r2))
-
-LOWFUNC(READ,WRITE,0,raw_pushfl,(void))
-{
- PUSHF();
-}
-LENDFUNC(READ,WRITE,0,raw_pushfl,(void))
-
-LOWFUNC(WRITE,READ,0,raw_popfl,(void))
-{
- POPF();
-}
-LENDFUNC(WRITE,READ,0,raw_popfl,(void))
-
-/* Generate floating-point instructions */
-static inline void x86_fadd_m(MEMR s)
-{
- ADDR32 FADDLm(s,X86_NOREG,X86_NOREG,1);
-}
-
-#else /* !USE_NEW_RTASM */
-
-const bool optimize_accum = true;
-const bool optimize_imm8 = true;
-const bool optimize_shift_once = true;
-
-/*************************************************************************
- * Actual encoding of the instructions on the target CPU *
- *************************************************************************/
-
-static inline int isaccum(int r)
-{
- return (r == EAX_INDEX);
-}
-
-static inline int isbyte(uae_s32 x)
-{
- return (x>=-128 && x<=127);
-}
-
-static inline int isword(uae_s32 x)
-{
- return (x>=-32768 && x<=32767);
-}
-
-LOWFUNC(NONE,WRITE,1,raw_push_l_r,(R4 r))
-{
- emit_byte(0x50+r);
-}
-LENDFUNC(NONE,WRITE,1,raw_push_l_r,(R4 r))
-
-LOWFUNC(NONE,READ,1,raw_pop_l_r,(R4 r))
-{
- emit_byte(0x58+r);
-}
-LENDFUNC(NONE,READ,1,raw_pop_l_r,(R4 r))
-
-LOWFUNC(NONE,READ,1,raw_pop_l_m,(MEMW d))
-{
- emit_byte(0x8f);
- emit_byte(0x05);
- emit_long(d);
-}
-LENDFUNC(NONE,READ,1,raw_pop_l_m,(MEMW d))
-
-LOWFUNC(WRITE,NONE,2,raw_bt_l_ri,(R4 r, IMM i))
-{
- emit_byte(0x0f);
- emit_byte(0xba);
- emit_byte(0xe0+r);
- emit_byte(i);
-}
-LENDFUNC(WRITE,NONE,2,raw_bt_l_ri,(R4 r, IMM i))
-
-LOWFUNC(WRITE,NONE,2,raw_bt_l_rr,(R4 r, R4 b))
-{
- emit_byte(0x0f);
- emit_byte(0xa3);
- emit_byte(0xc0+8*b+r);
-}
-LENDFUNC(WRITE,NONE,2,raw_bt_l_rr,(R4 r, R4 b))
-
-LOWFUNC(WRITE,NONE,2,raw_btc_l_ri,(RW4 r, IMM i))
-{
- emit_byte(0x0f);
- emit_byte(0xba);
- emit_byte(0xf8+r);
- emit_byte(i);
-}
-LENDFUNC(WRITE,NONE,2,raw_btc_l_ri,(RW4 r, IMM i))
-
-LOWFUNC(WRITE,NONE,2,raw_btc_l_rr,(RW4 r, R4 b))
-{
- emit_byte(0x0f);
- emit_byte(0xbb);
- emit_byte(0xc0+8*b+r);
-}
-LENDFUNC(WRITE,NONE,2,raw_btc_l_rr,(RW4 r, R4 b))
-
-
-LOWFUNC(WRITE,NONE,2,raw_btr_l_ri,(RW4 r, IMM i))
-{
- emit_byte(0x0f);
- emit_byte(0xba);
- emit_byte(0xf0+r);
- emit_byte(i);
-}
-LENDFUNC(WRITE,NONE,2,raw_btr_l_ri,(RW4 r, IMM i))
-
-LOWFUNC(WRITE,NONE,2,raw_btr_l_rr,(RW4 r, R4 b))
-{
- emit_byte(0x0f);
- emit_byte(0xb3);
- emit_byte(0xc0+8*b+r);
-}
-LENDFUNC(WRITE,NONE,2,raw_btr_l_rr,(RW4 r, R4 b))
-
-LOWFUNC(WRITE,NONE,2,raw_bts_l_ri,(RW4 r, IMM i))
-{
- emit_byte(0x0f);
- emit_byte(0xba);
- emit_byte(0xe8+r);
- emit_byte(i);
-}
-LENDFUNC(WRITE,NONE,2,raw_bts_l_ri,(RW4 r, IMM i))
-
-LOWFUNC(WRITE,NONE,2,raw_bts_l_rr,(RW4 r, R4 b))
-{
- emit_byte(0x0f);
- emit_byte(0xab);
- emit_byte(0xc0+8*b+r);
-}
-LENDFUNC(WRITE,NONE,2,raw_bts_l_rr,(RW4 r, R4 b))
-
-LOWFUNC(WRITE,NONE,2,raw_sub_w_ri,(RW2 d, IMM i))
-{
- emit_byte(0x66);
- if (isbyte(i)) {
- emit_byte(0x83);
- emit_byte(0xe8+d);
- emit_byte(i);
- }
- else {
- if (optimize_accum && isaccum(d))
- emit_byte(0x2d);
- else {
- emit_byte(0x81);
- emit_byte(0xe8+d);
- }
- emit_word(i);
- }
-}
-LENDFUNC(WRITE,NONE,2,raw_sub_w_ri,(RW2 d, IMM i))
-
-
-LOWFUNC(NONE,READ,2,raw_mov_l_rm,(W4 d, MEMR s))
-{
- emit_byte(0x8b);
- emit_byte(0x05+8*d);
- emit_long(s);
-}
-LENDFUNC(NONE,READ,2,raw_mov_l_rm,(W4 d, MEMR s))
-
-LOWFUNC(NONE,WRITE,2,raw_mov_l_mi,(MEMW d, IMM s))
-{
- emit_byte(0xc7);
- emit_byte(0x05);
- emit_long(d);
- emit_long(s);
-}
-LENDFUNC(NONE,WRITE,2,raw_mov_l_mi,(MEMW d, IMM s))
-
-LOWFUNC(NONE,WRITE,2,raw_mov_w_mi,(MEMW d, IMM s))
-{
- emit_byte(0x66);
- emit_byte(0xc7);
- emit_byte(0x05);
- emit_long(d);
- emit_word(s);
-}
-LENDFUNC(NONE,WRITE,2,raw_mov_w_mi,(MEMW d, IMM s))
-
-LOWFUNC(NONE,WRITE,2,raw_mov_b_mi,(MEMW d, IMM s))
-{
- emit_byte(0xc6);
- emit_byte(0x05);
- emit_long(d);
- emit_byte(s);
-}
-LENDFUNC(NONE,WRITE,2,raw_mov_b_mi,(MEMW d, IMM s))
-
-LOWFUNC(WRITE,RMW,2,raw_rol_b_mi,(MEMRW d, IMM i))
-{
- if (optimize_shift_once && (i == 1)) {
- emit_byte(0xd0);
- emit_byte(0x05);
- emit_long(d);
- }
- else {
- emit_byte(0xc0);
- emit_byte(0x05);
- emit_long(d);
- emit_byte(i);
- }
-}
-LENDFUNC(WRITE,RMW,2,raw_rol_b_mi,(MEMRW d, IMM i))
-
-LOWFUNC(WRITE,NONE,2,raw_rol_b_ri,(RW1 r, IMM i))
-{
- if (optimize_shift_once && (i == 1)) {
- emit_byte(0xd0);
- emit_byte(0xc0+r);
- }
- else {
- emit_byte(0xc0);
- emit_byte(0xc0+r);
- emit_byte(i);
- }
-}
-LENDFUNC(WRITE,NONE,2,raw_rol_b_ri,(RW1 r, IMM i))
-
-LOWFUNC(WRITE,NONE,2,raw_rol_w_ri,(RW2 r, IMM i))
-{
- emit_byte(0x66);
- emit_byte(0xc1);
- emit_byte(0xc0+r);
- emit_byte(i);
-}
-LENDFUNC(WRITE,NONE,2,raw_rol_w_ri,(RW2 r, IMM i))
-
-LOWFUNC(WRITE,NONE,2,raw_rol_l_ri,(RW4 r, IMM i))
-{
- if (optimize_shift_once && (i == 1)) {
- emit_byte(0xd1);
- emit_byte(0xc0+r);
- }
- else {
- emit_byte(0xc1);
- emit_byte(0xc0+r);
- emit_byte(i);
- }
-}
-LENDFUNC(WRITE,NONE,2,raw_rol_l_ri,(RW4 r, IMM i))
-
-LOWFUNC(WRITE,NONE,2,raw_rol_l_rr,(RW4 d, R1 r))
-{
- emit_byte(0xd3);
- emit_byte(0xc0+d);
-}
-LENDFUNC(WRITE,NONE,2,raw_rol_l_rr,(RW4 d, R1 r))
-
-LOWFUNC(WRITE,NONE,2,raw_rol_w_rr,(RW2 d, R1 r))
-{
- emit_byte(0x66);
- emit_byte(0xd3);
- emit_byte(0xc0+d);
-}
-LENDFUNC(WRITE,NONE,2,raw_rol_w_rr,(RW2 d, R1 r))
-
-LOWFUNC(WRITE,NONE,2,raw_rol_b_rr,(RW1 d, R1 r))
-{
- emit_byte(0xd2);
- emit_byte(0xc0+d);
-}
-LENDFUNC(WRITE,NONE,2,raw_rol_b_rr,(RW1 d, R1 r))
-
-LOWFUNC(WRITE,NONE,2,raw_shll_l_rr,(RW4 d, R1 r))
-{
- emit_byte(0xd3);
- emit_byte(0xe0+d);
-}
-LENDFUNC(WRITE,NONE,2,raw_shll_l_rr,(RW4 d, R1 r))
-
-LOWFUNC(WRITE,NONE,2,raw_shll_w_rr,(RW2 d, R1 r))
-{
- emit_byte(0x66);
- emit_byte(0xd3);
- emit_byte(0xe0+d);
-}
-LENDFUNC(WRITE,NONE,2,raw_shll_w_rr,(RW2 d, R1 r))
-
-LOWFUNC(WRITE,NONE,2,raw_shll_b_rr,(RW1 d, R1 r))
-{
- emit_byte(0xd2);
- emit_byte(0xe0+d);
-}
-LENDFUNC(WRITE,NONE,2,raw_shll_b_rr,(RW1 d, R1 r))
-
-LOWFUNC(WRITE,NONE,2,raw_ror_b_ri,(RW1 r, IMM i))
-{
- if (optimize_shift_once && (i == 1)) {
- emit_byte(0xd0);
- emit_byte(0xc8+r);
- }
- else {
- emit_byte(0xc0);
- emit_byte(0xc8+r);
- emit_byte(i);
- }
-}
-LENDFUNC(WRITE,NONE,2,raw_ror_b_ri,(RW1 r, IMM i))
-
-LOWFUNC(WRITE,NONE,2,raw_ror_w_ri,(RW2 r, IMM i))
-{
- emit_byte(0x66);
- emit_byte(0xc1);
- emit_byte(0xc8+r);
- emit_byte(i);
-}
-LENDFUNC(WRITE,NONE,2,raw_ror_w_ri,(RW2 r, IMM i))
-
-// gb-- used for making an fpcr value in compemu_fpp.cpp
-LOWFUNC(WRITE,READ,2,raw_or_l_rm,(RW4 d, MEMR s))
-{
- emit_byte(0x0b);
- emit_byte(0x05+8*d);
- emit_long(s);
-}
-LENDFUNC(WRITE,READ,2,raw_or_l_rm,(RW4 d, MEMR s))
-
-LOWFUNC(WRITE,NONE,2,raw_ror_l_ri,(RW4 r, IMM i))
-{
- if (optimize_shift_once && (i == 1)) {
- emit_byte(0xd1);
- emit_byte(0xc8+r);
- }
- else {
- emit_byte(0xc1);
- emit_byte(0xc8+r);
- emit_byte(i);
- }
-}
-LENDFUNC(WRITE,NONE,2,raw_ror_l_ri,(RW4 r, IMM i))
-
-LOWFUNC(WRITE,NONE,2,raw_ror_l_rr,(RW4 d, R1 r))
-{
- emit_byte(0xd3);
- emit_byte(0xc8+d);
-}
-LENDFUNC(WRITE,NONE,2,raw_ror_l_rr,(RW4 d, R1 r))
-
-LOWFUNC(WRITE,NONE,2,raw_ror_w_rr,(RW2 d, R1 r))
-{
- emit_byte(0x66);
- emit_byte(0xd3);
- emit_byte(0xc8+d);
-}
-LENDFUNC(WRITE,NONE,2,raw_ror_w_rr,(RW2 d, R1 r))
-
-LOWFUNC(WRITE,NONE,2,raw_ror_b_rr,(RW1 d, R1 r))
-{
- emit_byte(0xd2);
- emit_byte(0xc8+d);
-}
-LENDFUNC(WRITE,NONE,2,raw_ror_b_rr,(RW1 d, R1 r))
-
-LOWFUNC(WRITE,NONE,2,raw_shrl_l_rr,(RW4 d, R1 r))
-{
- emit_byte(0xd3);
- emit_byte(0xe8+d);
-}
-LENDFUNC(WRITE,NONE,2,raw_shrl_l_rr,(RW4 d, R1 r))
-
-LOWFUNC(WRITE,NONE,2,raw_shrl_w_rr,(RW2 d, R1 r))
-{
- emit_byte(0x66);
- emit_byte(0xd3);
- emit_byte(0xe8+d);
-}
-LENDFUNC(WRITE,NONE,2,raw_shrl_w_rr,(RW2 d, R1 r))
-
-LOWFUNC(WRITE,NONE,2,raw_shrl_b_rr,(RW1 d, R1 r))
-{
- emit_byte(0xd2);
- emit_byte(0xe8+d);
-}
-LENDFUNC(WRITE,NONE,2,raw_shrl_b_rr,(RW1 d, R1 r))
-
-LOWFUNC(WRITE,NONE,2,raw_shra_l_rr,(RW4 d, R1 r))
-{
- emit_byte(0xd3);
- emit_byte(0xf8+d);
-}
-LENDFUNC(WRITE,NONE,2,raw_shra_l_rr,(RW4 d, R1 r))
-
-LOWFUNC(WRITE,NONE,2,raw_shra_w_rr,(RW2 d, R1 r))
-{
- emit_byte(0x66);
- emit_byte(0xd3);
- emit_byte(0xf8+d);
-}
-LENDFUNC(WRITE,NONE,2,raw_shra_w_rr,(RW2 d, R1 r))
-
-LOWFUNC(WRITE,NONE,2,raw_shra_b_rr,(RW1 d, R1 r))
-{
- emit_byte(0xd2);
- emit_byte(0xf8+d);
-}
-LENDFUNC(WRITE,NONE,2,raw_shra_b_rr,(RW1 d, R1 r))
-
-LOWFUNC(WRITE,NONE,2,raw_shll_l_ri,(RW4 r, IMM i))
-{
- if (optimize_shift_once && (i == 1)) {
- emit_byte(0xd1);
- emit_byte(0xe0+r);
- }
- else {
- emit_byte(0xc1);
- emit_byte(0xe0+r);
- emit_byte(i);
- }
-}
-LENDFUNC(WRITE,NONE,2,raw_shll_l_ri,(RW4 r, IMM i))
-
-LOWFUNC(WRITE,NONE,2,raw_shll_w_ri,(RW2 r, IMM i))
-{
- emit_byte(0x66);
- emit_byte(0xc1);
- emit_byte(0xe0+r);
- emit_byte(i);
-}
-LENDFUNC(WRITE,NONE,2,raw_shll_w_ri,(RW2 r, IMM i))
-
-LOWFUNC(WRITE,NONE,2,raw_shll_b_ri,(RW1 r, IMM i))
-{
- if (optimize_shift_once && (i == 1)) {
- emit_byte(0xd0);
- emit_byte(0xe0+r);
- }
- else {
- emit_byte(0xc0);
- emit_byte(0xe0+r);
- emit_byte(i);
- }
-}
-LENDFUNC(WRITE,NONE,2,raw_shll_b_ri,(RW1 r, IMM i))
-
-LOWFUNC(WRITE,NONE,2,raw_shrl_l_ri,(RW4 r, IMM i))
-{
- if (optimize_shift_once && (i == 1)) {
- emit_byte(0xd1);
- emit_byte(0xe8+r);
- }
- else {
- emit_byte(0xc1);
- emit_byte(0xe8+r);
- emit_byte(i);
- }
-}
-LENDFUNC(WRITE,NONE,2,raw_shrl_l_ri,(RW4 r, IMM i))
-
-LOWFUNC(WRITE,NONE,2,raw_shrl_w_ri,(RW2 r, IMM i))
-{
- emit_byte(0x66);
- emit_byte(0xc1);
- emit_byte(0xe8+r);
- emit_byte(i);
-}
-LENDFUNC(WRITE,NONE,2,raw_shrl_w_ri,(RW2 r, IMM i))
-
-LOWFUNC(WRITE,NONE,2,raw_shrl_b_ri,(RW1 r, IMM i))
-{
- if (optimize_shift_once && (i == 1)) {
- emit_byte(0xd0);
- emit_byte(0xe8+r);
- }
- else {
- emit_byte(0xc0);
- emit_byte(0xe8+r);
- emit_byte(i);
- }
-}
-LENDFUNC(WRITE,NONE,2,raw_shrl_b_ri,(RW1 r, IMM i))
-
-LOWFUNC(WRITE,NONE,2,raw_shra_l_ri,(RW4 r, IMM i))
-{
- if (optimize_shift_once && (i == 1)) {
- emit_byte(0xd1);
- emit_byte(0xf8+r);
- }
- else {
- emit_byte(0xc1);
- emit_byte(0xf8+r);
- emit_byte(i);
- }
-}
-LENDFUNC(WRITE,NONE,2,raw_shra_l_ri,(RW4 r, IMM i))
-
-LOWFUNC(WRITE,NONE,2,raw_shra_w_ri,(RW2 r, IMM i))
-{
- emit_byte(0x66);
- emit_byte(0xc1);
- emit_byte(0xf8+r);
- emit_byte(i);
-}
-LENDFUNC(WRITE,NONE,2,raw_shra_w_ri,(RW2 r, IMM i))
-
-LOWFUNC(WRITE,NONE,2,raw_shra_b_ri,(RW1 r, IMM i))
-{
- if (optimize_shift_once && (i == 1)) {
- emit_byte(0xd0);
- emit_byte(0xf8+r);
- }
- else {
- emit_byte(0xc0);
- emit_byte(0xf8+r);
- emit_byte(i);
- }
-}
-LENDFUNC(WRITE,NONE,2,raw_shra_b_ri,(RW1 r, IMM i))
-
-LOWFUNC(WRITE,NONE,1,raw_sahf,(R2 dummy_ah))
-{
- emit_byte(0x9e);
-}
-LENDFUNC(WRITE,NONE,1,raw_sahf,(R2 dummy_ah))
-
-LOWFUNC(NONE,NONE,1,raw_cpuid,(R4 dummy_eax))
-{
- emit_byte(0x0f);
- emit_byte(0xa2);
-}
-LENDFUNC(NONE,NONE,1,raw_cpuid,(R4 dummy_eax))
-
-LOWFUNC(READ,NONE,1,raw_lahf,(W2 dummy_ah))
-{
- emit_byte(0x9f);
-}
-LENDFUNC(READ,NONE,1,raw_lahf,(W2 dummy_ah))
-
-LOWFUNC(READ,NONE,2,raw_setcc,(W1 d, IMM cc))
-{
- emit_byte(0x0f);
- emit_byte(0x90+cc);
- emit_byte(0xc0+d);
-}
-LENDFUNC(READ,NONE,2,raw_setcc,(W1 d, IMM cc))
-
-LOWFUNC(READ,WRITE,2,raw_setcc_m,(MEMW d, IMM cc))
-{
- emit_byte(0x0f);
- emit_byte(0x90+cc);
- emit_byte(0x05);
- emit_long(d);
-}
-LENDFUNC(READ,WRITE,2,raw_setcc_m,(MEMW d, IMM cc))
-
-LOWFUNC(READ,NONE,3,raw_cmov_l_rr,(RW4 d, R4 s, IMM cc))
-{
- if (have_cmov) {
- emit_byte(0x0f);
- emit_byte(0x40+cc);
- emit_byte(0xc0+8*d+s);
- }
- else { /* replacement using branch and mov */
- int uncc=(cc^1);
- emit_byte(0x70+uncc);
- emit_byte(2); /* skip next 2 bytes if not cc=true */
- emit_byte(0x89);
- emit_byte(0xc0+8*s+d);
- }
-}
-LENDFUNC(READ,NONE,3,raw_cmov_l_rr,(RW4 d, R4 s, IMM cc))
-
-LOWFUNC(WRITE,NONE,2,raw_bsf_l_rr,(W4 d, R4 s))
-{
- emit_byte(0x0f);
- emit_byte(0xbc);
- emit_byte(0xc0+8*d+s);
-}
-LENDFUNC(WRITE,NONE,2,raw_bsf_l_rr,(W4 d, R4 s))
-
-LOWFUNC(NONE,NONE,2,raw_sign_extend_16_rr,(W4 d, R2 s))
-{
- emit_byte(0x0f);
- emit_byte(0xbf);
- emit_byte(0xc0+8*d+s);
-}
-LENDFUNC(NONE,NONE,2,raw_sign_extend_16_rr,(W4 d, R2 s))
-
-LOWFUNC(NONE,NONE,2,raw_sign_extend_8_rr,(W4 d, R1 s))
-{
- emit_byte(0x0f);
- emit_byte(0xbe);
- emit_byte(0xc0+8*d+s);
-}
-LENDFUNC(NONE,NONE,2,raw_sign_extend_8_rr,(W4 d, R1 s))
-
-LOWFUNC(NONE,NONE,2,raw_zero_extend_16_rr,(W4 d, R2 s))
-{
- emit_byte(0x0f);
- emit_byte(0xb7);
- emit_byte(0xc0+8*d+s);
-}
-LENDFUNC(NONE,NONE,2,raw_zero_extend_16_rr,(W4 d, R2 s))
-
-LOWFUNC(NONE,NONE,2,raw_zero_extend_8_rr,(W4 d, R1 s))
-{
- emit_byte(0x0f);
- emit_byte(0xb6);
- emit_byte(0xc0+8*d+s);
-}
-LENDFUNC(NONE,NONE,2,raw_zero_extend_8_rr,(W4 d, R1 s))
-
-LOWFUNC(NONE,NONE,2,raw_imul_32_32,(RW4 d, R4 s))
-{
- emit_byte(0x0f);
- emit_byte(0xaf);
- emit_byte(0xc0+8*d+s);
-}
-LENDFUNC(NONE,NONE,2,raw_imul_32_32,(RW4 d, R4 s))
-
-LOWFUNC(NONE,NONE,2,raw_imul_64_32,(RW4 d, RW4 s))
-{
- if (d!=MUL_NREG1 || s!=MUL_NREG2) {
- jit_abort("Bad register in IMUL: d=%d, s=%d\n",d,s);
- }
- emit_byte(0xf7);
- emit_byte(0xea);
-}
-LENDFUNC(NONE,NONE,2,raw_imul_64_32,(RW4 d, RW4 s))
-
-LOWFUNC(NONE,NONE,2,raw_mul_64_32,(RW4 d, RW4 s))
-{
- if (d!=MUL_NREG1 || s!=MUL_NREG2) {
- jit_abort("Bad register in MUL: d=%d, s=%d",d,s);
- }
- emit_byte(0xf7);
- emit_byte(0xe2);
-}
-LENDFUNC(NONE,NONE,2,raw_mul_64_32,(RW4 d, RW4 s))
-
-LOWFUNC(NONE,NONE,2,raw_mul_32_32,(RW4 d, R4 s))
-{
- jit_abort("unsupported MUL"); /* %^$&%^$%#^ x86! */
- emit_byte(0x0f);
- emit_byte(0xaf);
- emit_byte(0xc0+8*d+s);
-}
-LENDFUNC(NONE,NONE,2,raw_mul_32_32,(RW4 d, R4 s))
-
-LOWFUNC(NONE,NONE,2,raw_mov_b_rr,(W1 d, R1 s))
-{
- emit_byte(0x88);
- emit_byte(0xc0+8*s+d);
-}
-LENDFUNC(NONE,NONE,2,raw_mov_b_rr,(W1 d, R1 s))
-
-LOWFUNC(NONE,NONE,2,raw_mov_w_rr,(W2 d, R2 s))
-{
- emit_byte(0x66);
- emit_byte(0x89);
- emit_byte(0xc0+8*s+d);
-}
-LENDFUNC(NONE,NONE,2,raw_mov_w_rr,(W2 d, R2 s))
-
-LOWFUNC(NONE,READ,4,raw_mov_l_rrm_indexed,(W4 d,R4 baser, R4 index, IMM factor))
-{
- int isebp=(baser==5)?0x40:0;
- int fi;
-
- switch(factor) {
- case 1: fi=0; break;
- case 2: fi=1; break;
- case 4: fi=2; break;
- case 8: fi=3; break;
- default: abort();
- }
-
-
- emit_byte(0x8b);
- emit_byte(0x04+8*d+isebp);
- emit_byte(baser+8*index+0x40*fi);
- if (isebp)
- emit_byte(0x00);
-}
-LENDFUNC(NONE,READ,4,raw_mov_l_rrm_indexed,(W4 d,R4 baser, R4 index, IMM factor))
-
-LOWFUNC(NONE,READ,4,raw_mov_w_rrm_indexed,(W2 d, R4 baser, R4 index, IMM factor))
-{
- int fi;
- int isebp;
-
- switch(factor) {
- case 1: fi=0; break;
- case 2: fi=1; break;
- case 4: fi=2; break;
- case 8: fi=3; break;
- default: abort();
- }
- isebp=(baser==5)?0x40:0;
-
- emit_byte(0x66);
- emit_byte(0x8b);
- emit_byte(0x04+8*d+isebp);
- emit_byte(baser+8*index+0x40*fi);
- if (isebp)
- emit_byte(0x00);
-}
-LENDFUNC(NONE,READ,4,raw_mov_w_rrm_indexed,(W2 d, R4 baser, R4 index, IMM factor))
-
-LOWFUNC(NONE,READ,4,raw_mov_b_rrm_indexed,(W1 d, R4 baser, R4 index, IMM factor))
-{
- int fi;
- int isebp;
-
- switch(factor) {
- case 1: fi=0; break;
- case 2: fi=1; break;
- case 4: fi=2; break;
- case 8: fi=3; break;
- default: abort();
- }
- isebp=(baser==5)?0x40:0;
-
- emit_byte(0x8a);
- emit_byte(0x04+8*d+isebp);
- emit_byte(baser+8*index+0x40*fi);
- if (isebp)
- emit_byte(0x00);
-}
-LENDFUNC(NONE,READ,4,raw_mov_b_rrm_indexed,(W1 d, R4 baser, R4 index, IMM factor))
-
-LOWFUNC(NONE,WRITE,4,raw_mov_l_mrr_indexed,(R4 baser, R4 index, IMM factor, R4 s))
-{
- int fi;
- int isebp;
-
- switch(factor) {
- case 1: fi=0; break;
- case 2: fi=1; break;
- case 4: fi=2; break;
- case 8: fi=3; break;
- default: abort();
- }
-
-
- isebp=(baser==5)?0x40:0;
-
- emit_byte(0x89);
- emit_byte(0x04+8*s+isebp);
- emit_byte(baser+8*index+0x40*fi);
- if (isebp)
- emit_byte(0x00);
-}
-LENDFUNC(NONE,WRITE,4,raw_mov_l_mrr_indexed,(R4 baser, R4 index, IMM factor, R4 s))
-
-LOWFUNC(NONE,WRITE,4,raw_mov_w_mrr_indexed,(R4 baser, R4 index, IMM factor, R2 s))
-{
- int fi;
- int isebp;
-
- switch(factor) {
- case 1: fi=0; break;
- case 2: fi=1; break;
- case 4: fi=2; break;
- case 8: fi=3; break;
- default: abort();
- }
- isebp=(baser==5)?0x40:0;
-
- emit_byte(0x66);
- emit_byte(0x89);
- emit_byte(0x04+8*s+isebp);
- emit_byte(baser+8*index+0x40*fi);
- if (isebp)
- emit_byte(0x00);
-}
-LENDFUNC(NONE,WRITE,4,raw_mov_w_mrr_indexed,(R4 baser, R4 index, IMM factor, R2 s))
-
-LOWFUNC(NONE,WRITE,4,raw_mov_b_mrr_indexed,(R4 baser, R4 index, IMM factor, R1 s))
-{
- int fi;
- int isebp;
-
- switch(factor) {
- case 1: fi=0; break;
- case 2: fi=1; break;
- case 4: fi=2; break;
- case 8: fi=3; break;
- default: abort();
- }
- isebp=(baser==5)?0x40:0;
-
- emit_byte(0x88);
- emit_byte(0x04+8*s+isebp);
- emit_byte(baser+8*index+0x40*fi);
- if (isebp)
- emit_byte(0x00);
-}
-LENDFUNC(NONE,WRITE,4,raw_mov_b_mrr_indexed,(R4 baser, R4 index, IMM factor, R1 s))
-
-LOWFUNC(NONE,WRITE,5,raw_mov_l_bmrr_indexed,(IMM base, R4 baser, R4 index, IMM factor, R4 s))
-{
- int fi;
-
- switch(factor) {
- case 1: fi=0; break;
- case 2: fi=1; break;
- case 4: fi=2; break;
- case 8: fi=3; break;
- default: abort();
- }
-
- emit_byte(0x89);
- emit_byte(0x84+8*s);
- emit_byte(baser+8*index+0x40*fi);
- emit_long(base);
-}
-LENDFUNC(NONE,WRITE,5,raw_mov_l_bmrr_indexed,(IMM base, R4 baser, R4 index, IMM factor, R4 s))
-
-LOWFUNC(NONE,WRITE,5,raw_mov_w_bmrr_indexed,(IMM base, R4 baser, R4 index, IMM factor, R2 s))
-{
- int fi;
-
- switch(factor) {
- case 1: fi=0; break;
- case 2: fi=1; break;
- case 4: fi=2; break;
- case 8: fi=3; break;
- default: abort();
- }
-
- emit_byte(0x66);
- emit_byte(0x89);
- emit_byte(0x84+8*s);
- emit_byte(baser+8*index+0x40*fi);
- emit_long(base);
-}
-LENDFUNC(NONE,WRITE,5,raw_mov_w_bmrr_indexed,(IMM base, R4 baser, R4 index, IMM factor, R2 s))
-
-LOWFUNC(NONE,WRITE,5,raw_mov_b_bmrr_indexed,(IMM base, R4 baser, R4 index, IMM factor, R1 s))
-{
- int fi;
-
- switch(factor) {
- case 1: fi=0; break;
- case 2: fi=1; break;
- case 4: fi=2; break;
- case 8: fi=3; break;
- default: abort();
- }
-
- emit_byte(0x88);
- emit_byte(0x84+8*s);
- emit_byte(baser+8*index+0x40*fi);
- emit_long(base);
-}
-LENDFUNC(NONE,WRITE,5,raw_mov_b_bmrr_indexed,(IMM base, R4 baser, R4 index, IMM factor, R1 s))
-
-LOWFUNC(NONE,READ,5,raw_mov_l_brrm_indexed,(W4 d, IMM base, R4 baser, R4 index, IMM factor))
-{
- int fi;
-
- switch(factor) {
- case 1: fi=0; break;
- case 2: fi=1; break;
- case 4: fi=2; break;
- case 8: fi=3; break;
- default: abort();
- }
-
- emit_byte(0x8b);
- emit_byte(0x84+8*d);
- emit_byte(baser+8*index+0x40*fi);
- emit_long(base);
-}
-LENDFUNC(NONE,READ,5,raw_mov_l_brrm_indexed,(W4 d, IMM base, R4 baser, R4 index, IMM factor))
-
-LOWFUNC(NONE,READ,5,raw_mov_w_brrm_indexed,(W2 d, IMM base, R4 baser, R4 index, IMM factor))
-{
- int fi;
-
- switch(factor) {
- case 1: fi=0; break;
- case 2: fi=1; break;
- case 4: fi=2; break;
- case 8: fi=3; break;
- default: abort();
- }
-
- emit_byte(0x66);
- emit_byte(0x8b);
- emit_byte(0x84+8*d);
- emit_byte(baser+8*index+0x40*fi);
- emit_long(base);
-}
-LENDFUNC(NONE,READ,5,raw_mov_w_brrm_indexed,(W2 d, IMM base, R4 baser, R4 index, IMM factor))
-
-LOWFUNC(NONE,READ,5,raw_mov_b_brrm_indexed,(W1 d, IMM base, R4 baser, R4 index, IMM factor))
-{
- int fi;
-
- switch(factor) {
- case 1: fi=0; break;
- case 2: fi=1; break;
- case 4: fi=2; break;
- case 8: fi=3; break;
- default: abort();
- }
-
- emit_byte(0x8a);
- emit_byte(0x84+8*d);
- emit_byte(baser+8*index+0x40*fi);
- emit_long(base);
-}
-LENDFUNC(NONE,READ,5,raw_mov_b_brrm_indexed,(W1 d, IMM base, R4 baser, R4 index, IMM factor))
-
-LOWFUNC(NONE,READ,4,raw_mov_l_rm_indexed,(W4 d, IMM base, R4 index, IMM factor))
-{
- int fi;
- switch(factor) {
- case 1: fi=0; break;
- case 2: fi=1; break;
- case 4: fi=2; break;
- case 8: fi=3; break;
- default:
- jit_abort("Bad factor %d in mov_l_rm_indexed!",factor);
- }
- emit_byte(0x8b);
- emit_byte(0x04+8*d);
- emit_byte(0x05+8*index+64*fi);
- emit_long(base);
-}
-LENDFUNC(NONE,READ,4,raw_mov_l_rm_indexed,(W4 d, IMM base, R4 index, IMM factor))
-
-LOWFUNC(NONE,READ,5,raw_cmov_l_rm_indexed,(W4 d, IMM base, R4 index, IMM factor, IMM cond))
-{
- int fi;
- switch(factor) {
- case 1: fi=0; break;
- case 2: fi=1; break;
- case 4: fi=2; break;
- case 8: fi=3; break;
- default:
- jit_abort("Bad factor %d in mov_l_rm_indexed!",factor);
- }
- if (have_cmov) {
- emit_byte(0x0f);
- emit_byte(0x40+cond);
- emit_byte(0x04+8*d);
- emit_byte(0x05+8*index+64*fi);
- emit_long(base);
- }
- else { /* replacement using branch and mov */
- int uncc=(cond^1);
- emit_byte(0x70+uncc);
- emit_byte(7); /* skip next 7 bytes if not cc=true */
- emit_byte(0x8b);
- emit_byte(0x04+8*d);
- emit_byte(0x05+8*index+64*fi);
- emit_long(base);
- }
-}
-LENDFUNC(NONE,READ,5,raw_cmov_l_rm_indexed,(W4 d, IMM base, R4 index, IMM factor, IMM cond))
-
-LOWFUNC(NONE,READ,3,raw_cmov_l_rm,(W4 d, IMM mem, IMM cond))
-{
- if (have_cmov) {
- emit_byte(0x0f);
- emit_byte(0x40+cond);
- emit_byte(0x05+8*d);
- emit_long(mem);
- }
- else { /* replacement using branch and mov */
- int uncc=(cond^1);
- emit_byte(0x70+uncc);
- emit_byte(6); /* skip next 6 bytes if not cc=true */
- emit_byte(0x8b);
- emit_byte(0x05+8*d);
- emit_long(mem);
- }
-}
-LENDFUNC(NONE,READ,3,raw_cmov_l_rm,(W4 d, IMM mem, IMM cond))
-
-LOWFUNC(NONE,READ,3,raw_mov_l_rR,(W4 d, R4 s, IMM offset))
-{
- Dif(!isbyte(offset)) abort();
- emit_byte(0x8b);
- emit_byte(0x40+8*d+s);
- emit_byte(offset);
-}
-LENDFUNC(NONE,READ,3,raw_mov_l_rR,(W4 d, R4 s, IMM offset))
-
-LOWFUNC(NONE,READ,3,raw_mov_w_rR,(W2 d, R4 s, IMM offset))
-{
- Dif(!isbyte(offset)) abort();
- emit_byte(0x66);
- emit_byte(0x8b);
- emit_byte(0x40+8*d+s);
- emit_byte(offset);
-}
-LENDFUNC(NONE,READ,3,raw_mov_w_rR,(W2 d, R4 s, IMM offset))
-
-LOWFUNC(NONE,READ,3,raw_mov_b_rR,(W1 d, R4 s, IMM offset))
-{
- Dif(!isbyte(offset)) abort();
- emit_byte(0x8a);
- emit_byte(0x40+8*d+s);
- emit_byte(offset);
-}
-LENDFUNC(NONE,READ,3,raw_mov_b_rR,(W1 d, R4 s, IMM offset))
-
-LOWFUNC(NONE,READ,3,raw_mov_l_brR,(W4 d, R4 s, IMM offset))
-{
- emit_byte(0x8b);
- emit_byte(0x80+8*d+s);
- emit_long(offset);
-}
-LENDFUNC(NONE,READ,3,raw_mov_l_brR,(W4 d, R4 s, IMM offset))
-
-LOWFUNC(NONE,READ,3,raw_mov_w_brR,(W2 d, R4 s, IMM offset))
-{
- emit_byte(0x66);
- emit_byte(0x8b);
- emit_byte(0x80+8*d+s);
- emit_long(offset);
-}
-LENDFUNC(NONE,READ,3,raw_mov_w_brR,(W2 d, R4 s, IMM offset))
-
-LOWFUNC(NONE,READ,3,raw_mov_b_brR,(W1 d, R4 s, IMM offset))
-{
- emit_byte(0x8a);
- emit_byte(0x80+8*d+s);
- emit_long(offset);
-}
-LENDFUNC(NONE,READ,3,raw_mov_b_brR,(W1 d, R4 s, IMM offset))
-
-LOWFUNC(NONE,WRITE,3,raw_mov_l_Ri,(R4 d, IMM i, IMM offset))
-{
- Dif(!isbyte(offset)) abort();
- emit_byte(0xc7);
- emit_byte(0x40+d);
- emit_byte(offset);
- emit_long(i);
-}
-LENDFUNC(NONE,WRITE,3,raw_mov_l_Ri,(R4 d, IMM i, IMM offset))
-
-LOWFUNC(NONE,WRITE,3,raw_mov_w_Ri,(R4 d, IMM i, IMM offset))
-{
- Dif(!isbyte(offset)) abort();
- emit_byte(0x66);
- emit_byte(0xc7);
- emit_byte(0x40+d);
- emit_byte(offset);
- emit_word(i);
-}
-LENDFUNC(NONE,WRITE,3,raw_mov_w_Ri,(R4 d, IMM i, IMM offset))
-
-LOWFUNC(NONE,WRITE,3,raw_mov_b_Ri,(R4 d, IMM i, IMM offset))
-{
- Dif(!isbyte(offset)) abort();
- emit_byte(0xc6);
- emit_byte(0x40+d);
- emit_byte(offset);
- emit_byte(i);
-}
-LENDFUNC(NONE,WRITE,3,raw_mov_b_Ri,(R4 d, IMM i, IMM offset))
-
-LOWFUNC(NONE,WRITE,3,raw_mov_l_Rr,(R4 d, R4 s, IMM offset))
-{
- Dif(!isbyte(offset)) abort();
- emit_byte(0x89);
- emit_byte(0x40+8*s+d);
- emit_byte(offset);
-}
-LENDFUNC(NONE,WRITE,3,raw_mov_l_Rr,(R4 d, R4 s, IMM offset))
-
-LOWFUNC(NONE,WRITE,3,raw_mov_w_Rr,(R4 d, R2 s, IMM offset))
-{
- Dif(!isbyte(offset)) abort();
- emit_byte(0x66);
- emit_byte(0x89);
- emit_byte(0x40+8*s+d);
- emit_byte(offset);
-}
-LENDFUNC(NONE,WRITE,3,raw_mov_w_Rr,(R4 d, R2 s, IMM offset))
-
-LOWFUNC(NONE,WRITE,3,raw_mov_b_Rr,(R4 d, R1 s, IMM offset))
-{
- Dif(!isbyte(offset)) abort();
- emit_byte(0x88);
- emit_byte(0x40+8*s+d);
- emit_byte(offset);
-}
-LENDFUNC(NONE,WRITE,3,raw_mov_b_Rr,(R4 d, R1 s, IMM offset))
-
-LOWFUNC(NONE,NONE,3,raw_lea_l_brr,(W4 d, R4 s, IMM offset))
-{
- if (optimize_imm8 && isbyte(offset)) {
- emit_byte(0x8d);
- emit_byte(0x40+8*d+s);
- emit_byte(offset);
- }
- else {
- emit_byte(0x8d);
- emit_byte(0x80+8*d+s);
- emit_long(offset);
- }
-}
-LENDFUNC(NONE,NONE,3,raw_lea_l_brr,(W4 d, R4 s, IMM offset))
-
-LOWFUNC(NONE,NONE,5,raw_lea_l_brr_indexed,(W4 d, R4 s, R4 index, IMM factor, IMM offset))
-{
- int fi;
-
- switch(factor) {
- case 1: fi=0; break;
- case 2: fi=1; break;
- case 4: fi=2; break;
- case 8: fi=3; break;
- default: abort();
- }
-
- if (optimize_imm8 && isbyte(offset)) {
- emit_byte(0x8d);
- emit_byte(0x44+8*d);
- emit_byte(0x40*fi+8*index+s);
- emit_byte(offset);
- }
- else {
- emit_byte(0x8d);
- emit_byte(0x84+8*d);
- emit_byte(0x40*fi+8*index+s);
- emit_long(offset);
- }
-}
-LENDFUNC(NONE,NONE,5,raw_lea_l_brr_indexed,(W4 d, R4 s, R4 index, IMM factor, IMM offset))
-
-LOWFUNC(NONE,NONE,4,raw_lea_l_rr_indexed,(W4 d, R4 s, R4 index, IMM factor))
-{
- int isebp=(s==5)?0x40:0;
- int fi;
-
- switch(factor) {
- case 1: fi=0; break;
- case 2: fi=1; break;
- case 4: fi=2; break;
- case 8: fi=3; break;
- default: abort();
- }
-
- emit_byte(0x8d);
- emit_byte(0x04+8*d+isebp);
- emit_byte(0x40*fi+8*index+s);
- if (isebp)
- emit_byte(0);
-}
-LENDFUNC(NONE,NONE,4,raw_lea_l_rr_indexed,(W4 d, R4 s, R4 index, IMM factor))
-
-LOWFUNC(NONE,WRITE,3,raw_mov_l_bRr,(R4 d, R4 s, IMM offset))
-{
- if (optimize_imm8 && isbyte(offset)) {
- emit_byte(0x89);
- emit_byte(0x40+8*s+d);
- emit_byte(offset);
- }
- else {
- emit_byte(0x89);
- emit_byte(0x80+8*s+d);
- emit_long(offset);
- }
+{
+ ADDR32 MOVLrm(s, offset, d, X86_NOREG, 1);
}
-LENDFUNC(NONE,WRITE,3,raw_mov_l_bRr,(R4 d, R4 s, IMM offset))
LOWFUNC(NONE,WRITE,3,raw_mov_w_bRr,(R4 d, R2 s, IMM offset))
{
- emit_byte(0x66);
- emit_byte(0x89);
- emit_byte(0x80+8*s+d);
- emit_long(offset);
+ ADDR32 MOVWrm(s, offset, d, X86_NOREG, 1);
}
-LENDFUNC(NONE,WRITE,3,raw_mov_w_bRr,(R4 d, R2 s, IMM offset))
LOWFUNC(NONE,WRITE,3,raw_mov_b_bRr,(R4 d, R1 s, IMM offset))
{
- if (optimize_imm8 && isbyte(offset)) {
- emit_byte(0x88);
- emit_byte(0x40+8*s+d);
- emit_byte(offset);
- }
- else {
- emit_byte(0x88);
- emit_byte(0x80+8*s+d);
- emit_long(offset);
- }
+ ADDR32 MOVBrm(s, offset, d, X86_NOREG, 1);
}
-LENDFUNC(NONE,WRITE,3,raw_mov_b_bRr,(R4 d, R1 s, IMM offset))
LOWFUNC(NONE,NONE,1,raw_bswap_32,(RW4 r))
{
- emit_byte(0x0f);
- emit_byte(0xc8+r);
+ BSWAPLr(r);
}
-LENDFUNC(NONE,NONE,1,raw_bswap_32,(RW4 r))
LOWFUNC(WRITE,NONE,1,raw_bswap_16,(RW2 r))
{
- emit_byte(0x66);
- emit_byte(0xc1);
- emit_byte(0xc0+r);
- emit_byte(0x08);
+ ROLWir(8, r);
}
-LENDFUNC(WRITE,NONE,1,raw_bswap_16,(RW2 r))
LOWFUNC(NONE,NONE,2,raw_mov_l_rr,(W4 d, R4 s))
{
- emit_byte(0x89);
- emit_byte(0xc0+8*s+d);
+ MOVLrr(s, d);
}
-LENDFUNC(NONE,NONE,2,raw_mov_l_rr,(W4 d, R4 s))
LOWFUNC(NONE,WRITE,2,raw_mov_l_mr,(IMM d, R4 s))
{
- emit_byte(0x89);
- emit_byte(0x05+8*s);
- emit_long(d);
+ ADDR32 MOVLrm(s, d, X86_NOREG, X86_NOREG, 1);
}
-LENDFUNC(NONE,WRITE,2,raw_mov_l_mr,(IMM d, R4 s))
LOWFUNC(NONE,WRITE,2,raw_mov_w_mr,(IMM d, R2 s))
{
- emit_byte(0x66);
- emit_byte(0x89);
- emit_byte(0x05+8*s);
- emit_long(d);
+ ADDR32 MOVWrm(s, d, X86_NOREG, X86_NOREG, 1);
}
-LENDFUNC(NONE,WRITE,2,raw_mov_w_mr,(IMM d, R2 s))
LOWFUNC(NONE,READ,2,raw_mov_w_rm,(W2 d, IMM s))
{
- emit_byte(0x66);
- emit_byte(0x8b);
- emit_byte(0x05+8*d);
- emit_long(s);
+ ADDR32 MOVWmr(s, X86_NOREG, X86_NOREG, 1, d);
}
-LENDFUNC(NONE,READ,2,raw_mov_w_rm,(W2 d, IMM s))
LOWFUNC(NONE,WRITE,2,raw_mov_b_mr,(IMM d, R1 s))
{
- emit_byte(0x88);
- emit_byte(0x05+8*(s&0xf)); /* XXX this handles %ah case (defined as 0x10+4) and others */
- emit_long(d);
+ ADDR32 MOVBrm(s, d, X86_NOREG, X86_NOREG, 1);
}
-LENDFUNC(NONE,WRITE,2,raw_mov_b_mr,(IMM d, R1 s))
LOWFUNC(NONE,READ,2,raw_mov_b_rm,(W1 d, IMM s))
{
- emit_byte(0x8a);
- emit_byte(0x05+8*d);
- emit_long(s);
+ ADDR32 MOVBmr(s, X86_NOREG, X86_NOREG, 1, d);
}
-LENDFUNC(NONE,READ,2,raw_mov_b_rm,(W1 d, IMM s))
LOWFUNC(NONE,NONE,2,raw_mov_l_ri,(W4 d, IMM s))
{
- emit_byte(0xb8+d);
- emit_long(s);
+ MOVLir(s, d);
}
-LENDFUNC(NONE,NONE,2,raw_mov_l_ri,(W4 d, IMM s))
LOWFUNC(NONE,NONE,2,raw_mov_w_ri,(W2 d, IMM s))
{
- emit_byte(0x66);
- emit_byte(0xb8+d);
- emit_word(s);
+ MOVWir(s, d);
}
-LENDFUNC(NONE,NONE,2,raw_mov_w_ri,(W2 d, IMM s))
LOWFUNC(NONE,NONE,2,raw_mov_b_ri,(W1 d, IMM s))
{
- emit_byte(0xb0+d);
- emit_byte(s);
+ MOVBir(s, d);
}
-LENDFUNC(NONE,NONE,2,raw_mov_b_ri,(W1 d, IMM s))
LOWFUNC(RMW,RMW,2,raw_adc_l_mi,(MEMRW d, IMM s))
{
- emit_byte(0x81);
- emit_byte(0x15);
- emit_long(d);
- emit_long(s);
+ ADDR32 ADCLim(s, d, X86_NOREG, X86_NOREG, 1);
}
-LENDFUNC(RMW,RMW,2,raw_adc_l_mi,(MEMRW d, IMM s))
-LOWFUNC(WRITE,RMW,2,raw_add_l_mi,(IMM d, IMM s))
+LOWFUNC(WRITE,RMW,2,raw_add_l_mi,(IMM d, IMM s))
{
- if (optimize_imm8 && isbyte(s)) {
- emit_byte(0x83);
- emit_byte(0x05);
- emit_long(d);
- emit_byte(s);
- }
- else {
- emit_byte(0x81);
- emit_byte(0x05);
- emit_long(d);
- emit_long(s);
- }
+ ADDR32 ADDLim(s, d, X86_NOREG, X86_NOREG, 1);
}
-LENDFUNC(WRITE,RMW,2,raw_add_l_mi,(IMM d, IMM s))
-LOWFUNC(WRITE,RMW,2,raw_add_w_mi,(IMM d, IMM s))
+LOWFUNC(WRITE,RMW,2,raw_add_w_mi,(IMM d, IMM s))
{
- emit_byte(0x66);
- emit_byte(0x81);
- emit_byte(0x05);
- emit_long(d);
- emit_word(s);
+ ADDR32 ADDWim(s, d, X86_NOREG, X86_NOREG, 1);
}
-LENDFUNC(WRITE,RMW,2,raw_add_w_mi,(IMM d, IMM s))
-LOWFUNC(WRITE,RMW,2,raw_add_b_mi,(IMM d, IMM s))
+LOWFUNC(WRITE,RMW,2,raw_add_b_mi,(IMM d, IMM s))
{
- emit_byte(0x80);
- emit_byte(0x05);
- emit_long(d);
- emit_byte(s);
+ ADDR32 ADDBim(s, d, X86_NOREG, X86_NOREG, 1);
}
-LENDFUNC(WRITE,RMW,2,raw_add_b_mi,(IMM d, IMM s))
LOWFUNC(WRITE,NONE,2,raw_test_l_ri,(R4 d, IMM i))
{
- if (optimize_accum && isaccum(d))
- emit_byte(0xa9);
- else {
- emit_byte(0xf7);
- emit_byte(0xc0+d);
- }
- emit_long(i);
+ TESTLir(i, d);
}
-LENDFUNC(WRITE,NONE,2,raw_test_l_ri,(R4 d, IMM i))
LOWFUNC(WRITE,NONE,2,raw_test_l_rr,(R4 d, R4 s))
{
- emit_byte(0x85);
- emit_byte(0xc0+8*s+d);
+ TESTLrr(s, d);
}
-LENDFUNC(WRITE,NONE,2,raw_test_l_rr,(R4 d, R4 s))
LOWFUNC(WRITE,NONE,2,raw_test_w_rr,(R2 d, R2 s))
{
- emit_byte(0x66);
- emit_byte(0x85);
- emit_byte(0xc0+8*s+d);
+ TESTWrr(s, d);
}
-LENDFUNC(WRITE,NONE,2,raw_test_w_rr,(R2 d, R2 s))
LOWFUNC(WRITE,NONE,2,raw_test_b_rr,(R1 d, R1 s))
{
- emit_byte(0x84);
- emit_byte(0xc0+8*s+d);
+ TESTBrr(s, d);
+}
+
+LOWFUNC(WRITE,READ,2,raw_test_b_mi,(IMM d, IMM s))
+{
+ ADDR32 TESTBim(s, d, X86_NOREG, X86_NOREG, 1);
}
-LENDFUNC(WRITE,NONE,2,raw_test_b_rr,(R1 d, R1 s))
LOWFUNC(WRITE,NONE,2,raw_xor_l_ri,(RW4 d, IMM i))
{
- emit_byte(0x81);
- emit_byte(0xf0+d);
- emit_long(i);
+ XORLir(i, d);
}
-LENDFUNC(WRITE,NONE,2,raw_xor_l_ri,(RW4 d, IMM i))
LOWFUNC(WRITE,NONE,2,raw_and_l_ri,(RW4 d, IMM i))
{
- if (optimize_imm8 && isbyte(i)) {
- emit_byte(0x83);
- emit_byte(0xe0+d);
- emit_byte(i);
- }
- else {
- if (optimize_accum && isaccum(d))
- emit_byte(0x25);
- else {
- emit_byte(0x81);
- emit_byte(0xe0+d);
- }
- emit_long(i);
- }
+ ANDLir(i, d);
}
-LENDFUNC(WRITE,NONE,2,raw_and_l_ri,(RW4 d, IMM i))
LOWFUNC(WRITE,NONE,2,raw_and_w_ri,(RW2 d, IMM i))
{
- emit_byte(0x66);
- if (optimize_imm8 && isbyte(i)) {
- emit_byte(0x83);
- emit_byte(0xe0+d);
- emit_byte(i);
- }
- else {
- if (optimize_accum && isaccum(d))
- emit_byte(0x25);
- else {
- emit_byte(0x81);
- emit_byte(0xe0+d);
- }
- emit_word(i);
- }
+ ANDWir(i, d);
}
-LENDFUNC(WRITE,NONE,2,raw_and_w_ri,(RW2 d, IMM i))
LOWFUNC(WRITE,NONE,2,raw_and_l,(RW4 d, R4 s))
{
- emit_byte(0x21);
- emit_byte(0xc0+8*s+d);
+ ANDLrr(s, d);
}
-LENDFUNC(WRITE,NONE,2,raw_and_l,(RW4 d, R4 s))
LOWFUNC(WRITE,NONE,2,raw_and_w,(RW2 d, R2 s))
{
- emit_byte(0x66);
- emit_byte(0x21);
- emit_byte(0xc0+8*s+d);
+ ANDWrr(s, d);
}
-LENDFUNC(WRITE,NONE,2,raw_and_w,(RW2 d, R2 s))
LOWFUNC(WRITE,NONE,2,raw_and_b,(RW1 d, R1 s))
{
- emit_byte(0x20);
- emit_byte(0xc0+8*s+d);
+ ANDBrr(s, d);
}
-LENDFUNC(WRITE,NONE,2,raw_and_b,(RW1 d, R1 s))
LOWFUNC(WRITE,NONE,2,raw_or_l_ri,(RW4 d, IMM i))
{
- if (optimize_imm8 && isbyte(i)) {
- emit_byte(0x83);
- emit_byte(0xc8+d);
- emit_byte(i);
- }
- else {
- if (optimize_accum && isaccum(d))
- emit_byte(0x0d);
- else {
- emit_byte(0x81);
- emit_byte(0xc8+d);
- }
- emit_long(i);
- }
+ ORLir(i, d);
}
-LENDFUNC(WRITE,NONE,2,raw_or_l_ri,(RW4 d, IMM i))
LOWFUNC(WRITE,NONE,2,raw_or_l,(RW4 d, R4 s))
{
- emit_byte(0x09);
- emit_byte(0xc0+8*s+d);
+ ORLrr(s, d);
}
-LENDFUNC(WRITE,NONE,2,raw_or_l,(RW4 d, R4 s))
LOWFUNC(WRITE,NONE,2,raw_or_w,(RW2 d, R2 s))
{
- emit_byte(0x66);
- emit_byte(0x09);
- emit_byte(0xc0+8*s+d);
+ ORWrr(s, d);
}
-LENDFUNC(WRITE,NONE,2,raw_or_w,(RW2 d, R2 s))
LOWFUNC(WRITE,NONE,2,raw_or_b,(RW1 d, R1 s))
{
- emit_byte(0x08);
- emit_byte(0xc0+8*s+d);
+ ORBrr(s, d);
}
-LENDFUNC(WRITE,NONE,2,raw_or_b,(RW1 d, R1 s))
LOWFUNC(RMW,NONE,2,raw_adc_l,(RW4 d, R4 s))
{
- emit_byte(0x11);
- emit_byte(0xc0+8*s+d);
+ ADCLrr(s, d);
}
-LENDFUNC(RMW,NONE,2,raw_adc_l,(RW4 d, R4 s))
LOWFUNC(RMW,NONE,2,raw_adc_w,(RW2 d, R2 s))
{
- emit_byte(0x66);
- emit_byte(0x11);
- emit_byte(0xc0+8*s+d);
+ ADCWrr(s, d);
}
-LENDFUNC(RMW,NONE,2,raw_adc_w,(RW2 d, R2 s))
LOWFUNC(RMW,NONE,2,raw_adc_b,(RW1 d, R1 s))
{
- emit_byte(0x10);
- emit_byte(0xc0+8*s+d);
+ ADCBrr(s, d);
}
-LENDFUNC(RMW,NONE,2,raw_adc_b,(RW1 d, R1 s))
LOWFUNC(WRITE,NONE,2,raw_add_l,(RW4 d, R4 s))
{
- emit_byte(0x01);
- emit_byte(0xc0+8*s+d);
+ ADDLrr(s, d);
}
-LENDFUNC(WRITE,NONE,2,raw_add_l,(RW4 d, R4 s))
LOWFUNC(WRITE,NONE,2,raw_add_w,(RW2 d, R2 s))
{
- emit_byte(0x66);
- emit_byte(0x01);
- emit_byte(0xc0+8*s+d);
+ ADDWrr(s, d);
}
-LENDFUNC(WRITE,NONE,2,raw_add_w,(RW2 d, R2 s))
LOWFUNC(WRITE,NONE,2,raw_add_b,(RW1 d, R1 s))
{
- emit_byte(0x00);
- emit_byte(0xc0+8*s+d);
+ ADDBrr(s, d);
}
-LENDFUNC(WRITE,NONE,2,raw_add_b,(RW1 d, R1 s))
LOWFUNC(WRITE,NONE,2,raw_sub_l_ri,(RW4 d, IMM i))
{
- if (isbyte(i)) {
- emit_byte(0x83);
- emit_byte(0xe8+d);
- emit_byte(i);
- }
- else {
- if (optimize_accum && isaccum(d))
- emit_byte(0x2d);
- else {
- emit_byte(0x81);
- emit_byte(0xe8+d);
- }
- emit_long(i);
- }
+ SUBLir(i, d);
}
-LENDFUNC(WRITE,NONE,2,raw_sub_l_ri,(RW4 d, IMM i))
LOWFUNC(WRITE,NONE,2,raw_sub_b_ri,(RW1 d, IMM i))
{
- if (optimize_accum && isaccum(d))
- emit_byte(0x2c);
- else {
- emit_byte(0x80);
- emit_byte(0xe8+d);
- }
- emit_byte(i);
+ SUBBir(i, d);
}
-LENDFUNC(WRITE,NONE,2,raw_sub_b_ri,(RW1 d, IMM i))
LOWFUNC(WRITE,NONE,2,raw_add_l_ri,(RW4 d, IMM i))
{
- if (isbyte(i)) {
- emit_byte(0x83);
- emit_byte(0xc0+d);
- emit_byte(i);
- }
- else {
- if (optimize_accum && isaccum(d))
- emit_byte(0x05);
- else {
- emit_byte(0x81);
- emit_byte(0xc0+d);
- }
- emit_long(i);
- }
+ ADDLir(i, d);
}
-LENDFUNC(WRITE,NONE,2,raw_add_l_ri,(RW4 d, IMM i))
LOWFUNC(WRITE,NONE,2,raw_add_w_ri,(RW2 d, IMM i))
{
- emit_byte(0x66);
- if (isbyte(i)) {
- emit_byte(0x83);
- emit_byte(0xc0+d);
- emit_byte(i);
- }
- else {
- if (optimize_accum && isaccum(d))
- emit_byte(0x05);
- else {
- emit_byte(0x81);
- emit_byte(0xc0+d);
- }
- emit_word(i);
- }
+ ADDWir(i, d);
}
-LENDFUNC(WRITE,NONE,2,raw_add_w_ri,(RW2 d, IMM i))
LOWFUNC(WRITE,NONE,2,raw_add_b_ri,(RW1 d, IMM i))
{
- if (optimize_accum && isaccum(d))
- emit_byte(0x04);
- else {
- emit_byte(0x80);
- emit_byte(0xc0+d);
- }
- emit_byte(i);
+ ADDBir(i, d);
}
-LENDFUNC(WRITE,NONE,2,raw_add_b_ri,(RW1 d, IMM i))
LOWFUNC(RMW,NONE,2,raw_sbb_l,(RW4 d, R4 s))
{
- emit_byte(0x19);
- emit_byte(0xc0+8*s+d);
+ SBBLrr(s, d);
}
-LENDFUNC(RMW,NONE,2,raw_sbb_l,(RW4 d, R4 s))
LOWFUNC(RMW,NONE,2,raw_sbb_w,(RW2 d, R2 s))
{
- emit_byte(0x66);
- emit_byte(0x19);
- emit_byte(0xc0+8*s+d);
+ SBBWrr(s, d);
}
-LENDFUNC(RMW,NONE,2,raw_sbb_w,(RW2 d, R2 s))
LOWFUNC(RMW,NONE,2,raw_sbb_b,(RW1 d, R1 s))
{
- emit_byte(0x18);
- emit_byte(0xc0+8*s+d);
+ SBBBrr(s, d);
}
-LENDFUNC(RMW,NONE,2,raw_sbb_b,(RW1 d, R1 s))
LOWFUNC(WRITE,NONE,2,raw_sub_l,(RW4 d, R4 s))
{
- emit_byte(0x29);
- emit_byte(0xc0+8*s+d);
+ SUBLrr(s, d);
}
-LENDFUNC(WRITE,NONE,2,raw_sub_l,(RW4 d, R4 s))
LOWFUNC(WRITE,NONE,2,raw_sub_w,(RW2 d, R2 s))
{
- emit_byte(0x66);
- emit_byte(0x29);
- emit_byte(0xc0+8*s+d);
+ SUBWrr(s, d);
}
-LENDFUNC(WRITE,NONE,2,raw_sub_w,(RW2 d, R2 s))
LOWFUNC(WRITE,NONE,2,raw_sub_b,(RW1 d, R1 s))
{
- emit_byte(0x28);
- emit_byte(0xc0+8*s+d);
+ SUBBrr(s, d);
}
-LENDFUNC(WRITE,NONE,2,raw_sub_b,(RW1 d, R1 s))
LOWFUNC(WRITE,NONE,2,raw_cmp_l,(R4 d, R4 s))
{
- emit_byte(0x39);
- emit_byte(0xc0+8*s+d);
+ CMPLrr(s, d);
}
-LENDFUNC(WRITE,NONE,2,raw_cmp_l,(R4 d, R4 s))
LOWFUNC(WRITE,NONE,2,raw_cmp_l_ri,(R4 r, IMM i))
{
- if (optimize_imm8 && isbyte(i)) {
- emit_byte(0x83);
- emit_byte(0xf8+r);
- emit_byte(i);
- }
- else {
- if (optimize_accum && isaccum(r))
- emit_byte(0x3d);
- else {
- emit_byte(0x81);
- emit_byte(0xf8+r);
- }
- emit_long(i);
- }
+ CMPLir(i, r);
}
-LENDFUNC(WRITE,NONE,2,raw_cmp_l_ri,(R4 r, IMM i))
LOWFUNC(WRITE,NONE,2,raw_cmp_w,(R2 d, R2 s))
{
- emit_byte(0x66);
- emit_byte(0x39);
- emit_byte(0xc0+8*s+d);
+ CMPWrr(s, d);
}
-LENDFUNC(WRITE,NONE,2,raw_cmp_w,(R2 d, R2 s))
LOWFUNC(WRITE,READ,2,raw_cmp_b_mi,(MEMR d, IMM s))
{
- emit_byte(0x80);
- emit_byte(0x3d);
- emit_long(d);
- emit_byte(s);
+ ADDR32 CMPBim(s, d, X86_NOREG, X86_NOREG, 1);
}
-LENDFUNC(WRITE,READ,2,raw_cmp_l_mi,(MEMR d, IMM s))
LOWFUNC(WRITE,NONE,2,raw_cmp_b_ri,(R1 d, IMM i))
{
- if (optimize_accum && isaccum(d))
- emit_byte(0x3c);
- else {
- emit_byte(0x80);
- emit_byte(0xf8+d);
- }
- emit_byte(i);
+ CMPBir(i, d);
}
-LENDFUNC(WRITE,NONE,2,raw_cmp_b_ri,(R1 d, IMM i))
LOWFUNC(WRITE,NONE,2,raw_cmp_b,(R1 d, R1 s))
{
- emit_byte(0x38);
- emit_byte(0xc0+8*s+d);
+ CMPBrr(s, d);
}
-LENDFUNC(WRITE,NONE,2,raw_cmp_b,(R1 d, R1 s))
LOWFUNC(WRITE,READ,4,raw_cmp_l_rm_indexed,(R4 d, IMM offset, R4 index, IMM factor))
{
- int fi;
-
- switch(factor) {
- case 1: fi=0; break;
- case 2: fi=1; break;
- case 4: fi=2; break;
- case 8: fi=3; break;
- default: abort();
- }
- emit_byte(0x39);
- emit_byte(0x04+8*d);
- emit_byte(5+8*index+0x40*fi);
- emit_long(offset);
+ ADDR32 CMPLmr(offset, X86_NOREG, index, factor, d);
}
-LENDFUNC(WRITE,READ,4,raw_cmp_l_rm_indexed,(R4 d, IMM offset, R4 index, IMM factor))
LOWFUNC(WRITE,NONE,2,raw_xor_l,(RW4 d, R4 s))
{
- emit_byte(0x31);
- emit_byte(0xc0+8*s+d);
+ XORLrr(s, d);
}
-LENDFUNC(WRITE,NONE,2,raw_xor_l,(RW4 d, R4 s))
LOWFUNC(WRITE,NONE,2,raw_xor_w,(RW2 d, R2 s))
{
- emit_byte(0x66);
- emit_byte(0x31);
- emit_byte(0xc0+8*s+d);
+ XORWrr(s, d);
}
-LENDFUNC(WRITE,NONE,2,raw_xor_w,(RW2 d, R2 s))
LOWFUNC(WRITE,NONE,2,raw_xor_b,(RW1 d, R1 s))
{
- emit_byte(0x30);
- emit_byte(0xc0+8*s+d);
+ XORBrr(s, d);
}
-LENDFUNC(WRITE,NONE,2,raw_xor_b,(RW1 d, R1 s))
LOWFUNC(WRITE,RMW,2,raw_sub_l_mi,(MEMRW d, IMM s))
{
- if (optimize_imm8 && isbyte(s)) {
- emit_byte(0x83);
- emit_byte(0x2d);
- emit_long(d);
- emit_byte(s);
- }
- else {
- emit_byte(0x81);
- emit_byte(0x2d);
- emit_long(d);
- emit_long(s);
- }
+ ADDR32 SUBLim(s, d, X86_NOREG, X86_NOREG, 1);
}
-LENDFUNC(WRITE,RMW,2,raw_sub_l_mi,(MEMRW d, IMM s))
LOWFUNC(WRITE,READ,2,raw_cmp_l_mi,(MEMR d, IMM s))
{
- if (optimize_imm8 && isbyte(s)) {
- emit_byte(0x83);
- emit_byte(0x3d);
- emit_long(d);
- emit_byte(s);
- }
- else {
- emit_byte(0x81);
- emit_byte(0x3d);
- emit_long(d);
- emit_long(s);
- }
+ ADDR32 CMPLim(s, d, X86_NOREG, X86_NOREG, 1);
}
-LENDFUNC(WRITE,READ,2,raw_cmp_l_mi,(MEMR d, IMM s))
LOWFUNC(NONE,NONE,2,raw_xchg_l_rr,(RW4 r1, RW4 r2))
{
- emit_byte(0x87);
- emit_byte(0xc0+8*r1+r2);
+ XCHGLrr(r2, r1);
}
-LENDFUNC(NONE,NONE,2,raw_xchg_l_rr,(RW4 r1, RW4 r2))
LOWFUNC(NONE,NONE,2,raw_xchg_b_rr,(RW4 r1, RW4 r2))
{
- emit_byte(0x86);
- emit_byte(0xc0+8*(r1&0xf)+(r2&0xf)); /* XXX this handles upper-halves registers (e.g. %ah defined as 0x10+4) */
+ XCHGBrr(r2, r1);
}
-LENDFUNC(NONE,NONE,2,raw_xchg_l_rr,(RW4 r1, RW4 r2))
-
-/*************************************************************************
- * FIXME: mem access modes probably wrong *
- *************************************************************************/
LOWFUNC(READ,WRITE,0,raw_pushfl,(void))
{
- emit_byte(0x9c);
+ PUSHF();
}
-LENDFUNC(READ,WRITE,0,raw_pushfl,(void))
LOWFUNC(WRITE,READ,0,raw_popfl,(void))
{
- emit_byte(0x9d);
+ POPF();
}
-LENDFUNC(WRITE,READ,0,raw_popfl,(void))
/* Generate floating-point instructions */
static inline void x86_fadd_m(MEMR s)
{
- emit_byte(0xdc);
- emit_byte(0x05);
- emit_long(s);
+ ADDR32 FADDLm(s,X86_NOREG,X86_NOREG,1);
}
-#endif /* USE_NEW_RTASM */
/*************************************************************************
* Unoptimizable stuff --- jump *
static inline void raw_call_r(R4 r)
{
-#if USE_NEW_RTASM
CALLsr(r);
-#else
- emit_byte(0xff);
- emit_byte(0xd0+r);
-#endif
}
static inline void raw_call_m_indexed(uae_u32 base, uae_u32 r, uae_u32 m)
{
-#if USE_NEW_RTASM
ADDR32 CALLsm(base, X86_NOREG, r, m);
-#else
- int mu;
- switch(m) {
- case 1: mu=0; break;
- case 2: mu=1; break;
- case 4: mu=2; break;
- case 8: mu=3; break;
- default: abort();
- }
- emit_byte(0xff);
- emit_byte(0x14);
- emit_byte(0x05+8*r+0x40*mu);
- emit_long(base);
-#endif
}
static inline void raw_jmp_r(R4 r)
{
-#if USE_NEW_RTASM
JMPsr(r);
-#else
- emit_byte(0xff);
- emit_byte(0xe0+r);
-#endif
}
static inline void raw_jmp_m_indexed(uae_u32 base, uae_u32 r, uae_u32 m)
{
-#if USE_NEW_RTASM
ADDR32 JMPsm(base, X86_NOREG, r, m);
-#else
- int mu;
- switch (m) {
- case 1: mu=0; break;
- case 2: mu=1; break;
- case 4: mu=2; break;
- case 8: mu=3; break;
- default: abort();
- }
- emit_byte(0xff);
- emit_byte(0x24);
- emit_byte(0x05+8*r+0x40*mu);
- emit_long(base);
-#endif
}
static inline void raw_jmp_m(uae_u32 base)
static inline void raw_call(uae_u32 t)
{
-#if USE_NEW_RTASM
ADDR32 CALLm(t);
-#else
- emit_byte(0xe8);
- emit_long(t-(uintptr)target-4);
-#endif
}
static inline void raw_jmp(uae_u32 t)
{
-#if USE_NEW_RTASM
ADDR32 JMPm(t);
-#else
- emit_byte(0xe9);
- emit_long(t-(uintptr)target-4);
-#endif
}
-static inline void raw_jl(uae_u32 t)
+static inline void raw_jcc_l_oponly(int cc)
{
emit_byte(0x0f);
- emit_byte(0x8c);
- emit_long(t-(uintptr)target-4);
+ emit_byte(0x80+cc);
}
-static inline void raw_jz(uae_u32 t)
+static inline void raw_jz_l_oponly(void)
{
- emit_byte(0x0f);
- emit_byte(0x84);
- emit_long(t-(uintptr)target-4);
+ raw_jcc_l_oponly(NATIVE_CC_EQ);
}
-static inline void raw_jnz(uae_u32 t)
+static inline void raw_jnz_l_oponly(void)
{
- emit_byte(0x0f);
- emit_byte(0x85);
+ raw_jcc_l_oponly(NATIVE_CC_NE);
+}
+
+static inline void raw_jl(uae_u32 t)
+{
+ raw_jcc_l_oponly(NATIVE_CC_LT);
emit_long(t-(uintptr)target-4);
}
-static inline void raw_jnz_l_oponly(void)
+static inline void raw_jz(uae_u32 t)
{
- emit_byte(0x0f);
- emit_byte(0x85);
+ raw_jz_l_oponly();
+ emit_long(t-(uintptr)target-4);
}
-static inline void raw_jcc_l_oponly(int cc)
+static inline void raw_jnz(uae_u32 t)
{
- emit_byte(0x0f);
- emit_byte(0x80+cc);
+ raw_jnz_l_oponly();
+ emit_long(t-(uintptr)target-4);
}
-static inline void raw_jnz_b_oponly(void)
+static inline void raw_jcc_b_oponly(int cc)
{
- emit_byte(0x75);
+ emit_byte(0x70+cc);
}
-static inline void raw_jz_b_oponly(void)
+static inline void raw_jnz_b_oponly(void)
{
- emit_byte(0x74);
+ raw_jcc_b_oponly(NATIVE_CC_NE);
}
-static inline void raw_jcc_b_oponly(int cc)
+static inline void raw_jz_b_oponly(void)
{
- emit_byte(0x70+cc);
+ raw_jcc_b_oponly(NATIVE_CC_EQ);
}
static inline void raw_jmp_l_oponly(void)
live.nat[r].nholds=0;
}
-#define FLAG_NREG1_FLAGREG 0 /* Set to -1 if any register will do */
+#define FLAG_NREG1_FLAGREG EAX_INDEX /* Set to -1 if any register will do */
static inline void raw_flags_to_reg_FLAGREG(int r)
{
raw_lahf(0); /* Most flags in AH */
#endif
}
-#define FLAG_NREG2_FLAGREG 0 /* Set to -1 if any register will do */
+#define FLAG_NREG2_FLAGREG EAX_INDEX /* Set to -1 if any register will do */
static inline void raw_reg_to_flags_FLAGREG(int r)
{
raw_cmp_b_ri(r,-127); /* set V */
raw_sahf(0);
}
-#define FLAG_NREG3_FLAGREG 0 /* Set to -1 if any register will do */
+#define FLAG_NREG3_FLAGREG EAX_INDEX /* Set to -1 if any register will do */
static __inline__ void raw_flags_set_zero_FLAGREG(int s, int tmp)
{
raw_mov_l_rr(tmp,s);
/* Try to use the LAHF/SETO method on x86_64 since it is faster.
This can't be the default because some older CPUs don't support
LAHF/SAHF in long mode. */
-static int FLAG_NREG1_FLAGGEN = 0;
+static int FLAG_NREG1_FLAGGEN = EAX_INDEX;
static inline void raw_flags_to_reg_FLAGGEN(int r)
{
if (have_lahf_lm) {
raw_flags_to_reg_FLAGSTK(r);
}
-static int FLAG_NREG2_FLAGGEN = 0;
+static int FLAG_NREG2_FLAGGEN = EAX_INDEX;
static inline void raw_reg_to_flags_FLAGGEN(int r)
{
if (have_lahf_lm) {
raw_reg_to_flags_FLAGSTK(r);
}
-static int FLAG_NREG3_FLAGGEN = 0;
+static int FLAG_NREG3_FLAGGEN = EAX_INDEX;
static inline void raw_flags_set_zero_FLAGGEN(int s, int tmp)
{
if (have_lahf_lm)
if (have_lahf_lm) {
FLAG_NREG1_FLAGGEN = FLAG_NREG1_FLAGREG;
FLAG_NREG2_FLAGGEN = FLAG_NREG2_FLAGREG;
- FLAG_NREG1_FLAGGEN = FLAG_NREG3_FLAGREG;
+ FLAG_NREG3_FLAGGEN = FLAG_NREG3_FLAGREG;
}
else {
FLAG_NREG1_FLAGGEN = FLAG_NREG1_FLAGSTK;
FLAG_NREG2_FLAGGEN = FLAG_NREG2_FLAGSTK;
- FLAG_NREG1_FLAGGEN = FLAG_NREG3_FLAGSTK;
+ FLAG_NREG3_FLAGGEN = FLAG_NREG3_FLAGSTK;
}
}
#endif
/* Apparently, there are enough instructions between flag store and
flag reload to avoid the partial memory stall */
-static inline void raw_load_flagreg(uae_u32 target, uae_u32 r)
+static inline void raw_load_flagreg(uae_u32 target)
{
-#if 1
- raw_mov_l_rm(target,(uintptr)live.state[r].mem);
-#else
- raw_mov_b_rm(target,(uintptr)live.state[r].mem);
- raw_mov_b_rm(target+4,((uintptr)live.state[r].mem)+1);
-#endif
+ /* attention: in 64bit mode, relies on LITTE_ENDIANESS of regflags.cznv */
+ raw_mov_l_rm(target,(uintptr)live.state[FLAGTMP].mem);
}
-#ifdef UAE
-/* FLAGX is word-sized */
-#else
-/* FLAGX is byte sized, and we *do* write it at that size */
-#endif
-static inline void raw_load_flagx(uae_u32 target, uae_u32 r)
+static inline void raw_load_flagx(uae_u32 target)
{
-#ifdef UAE
- if (live.nat[target].canword)
-#else
+#if FLAGBIT_X < 8
if (live.nat[target].canbyte)
- raw_mov_b_rm(target,(uintptr)live.state[r].mem);
- else if (live.nat[target].canword)
+ raw_mov_b_rm(target,(uintptr)live.state[FLAGX].mem);
+ else
#endif
- raw_mov_w_rm(target,(uintptr)live.state[r].mem);
+ if (live.nat[target].canword)
+ raw_mov_w_rm(target,(uintptr)live.state[FLAGX].mem);
else
- raw_mov_l_rm(target,(uintptr)live.state[r].mem);
+ raw_mov_l_rm(target,(uintptr)live.state[FLAGX].mem);
}
static inline void raw_dec_sp(int off)
}
/* FP helper functions */
-#if USE_NEW_RTASM
#define DEFINE_OP(NAME, GEN) \
-static inline void raw_##NAME(uint32 m) \
+static inline void raw_##NAME(uintptr m) \
{ \
GEN(m, X86_NOREG, X86_NOREG, 1); \
}
DEFINE_OP(fstpt, FSTPTm);
DEFINE_OP(fldt, FLDTm);
DEFINE_OP(fistpl, FISTPLm);
-#else
-#define DEFINE_OP(NAME, OP1, OP2) \
-static inline void raw_##NAME(uint32 m) \
-{ \
- emit_byte(OP1); \
- emit_byte(OP2); \
- emit_long(m); \
-}
-DEFINE_OP(fstl, 0xdd, 0x15);
-DEFINE_OP(fstpl, 0xdd, 0x1d);
-DEFINE_OP(fldl, 0xdd, 0x05);
-DEFINE_OP(fildl, 0xdb, 0x05);
-DEFINE_OP(fistl, 0xdb, 0x15);
-DEFINE_OP(flds, 0xd9, 0x05);
-DEFINE_OP(fsts, 0xd9, 0x15);
-DEFINE_OP(fstpt, 0xdb, 0x3d);
-DEFINE_OP(fldt, 0xdb, 0x2d);
-DEFINE_OP(fistpl, 0xdb, 0x1d);
-#endif
#undef DEFINE_OP
-LOWFUNC(NONE,WRITE,2,raw_fmov_mr,(MEMW m, FR r))
+LOWFUNC(NONE,WRITE,2,raw_fmov_mr,(MEMPTRW m, FR r))
{
make_tos(r);
raw_fstl(m);
}
-LENDFUNC(NONE,WRITE,2,raw_fmov_mr,(MEMW m, FR r))
-LOWFUNC(NONE,WRITE,2,raw_fmov_mr_drop,(MEMW m, FR r))
+LOWFUNC(NONE,WRITE,2,raw_fmov_mr_drop,(MEMPTRW m, FR r))
{
make_tos(r);
raw_fstpl(m);
live.tos--;
live.spos[r]=-2;
}
-LENDFUNC(NONE,WRITE,2,raw_fmov_mr,(MEMW m, FR r))
-LOWFUNC(NONE,READ,2,raw_fmov_rm,(FW r, MEMR m))
+LOWFUNC(NONE,READ,2,raw_fmov_rm,(FW r, MEMPTRR m))
{
raw_fldl(m);
tos_make(r);
}
-LENDFUNC(NONE,READ,2,raw_fmov_rm,(FW r, MEMR m))
-LOWFUNC(NONE,READ,2,raw_fmovi_rm,(FW r, MEMR m))
+LOWFUNC(NONE,READ,2,raw_fmovi_rm,(FW r, MEMPTRR m))
{
raw_fildl(m);
tos_make(r);
}
-LENDFUNC(NONE,READ,2,raw_fmovi_rm,(FW r, MEMR m))
-LOWFUNC(NONE,WRITE,2,raw_fmovi_mr,(MEMW m, FR r))
+LOWFUNC(NONE,WRITE,2,raw_fmovi_mr,(MEMPTRW m, FR r))
{
make_tos(r);
raw_fistl(m);
}
-LENDFUNC(NONE,WRITE,2,raw_fmovi_mr,(MEMW m, FR r))
-LOWFUNC(NONE,WRITE,3,raw_fmovi_mrb,(MEMW m, FR r, double *bounds))
+LOWFUNC(NONE,WRITE,3,raw_fmovi_mrb,(MEMPTRW m, FR r, double *bounds))
{
/* Clamp value to the given range and convert to integer. */
/* Store to destination */
raw_fistpl(m);
}
-LENDFUNC(NONE,WRITE,3,raw_fmovi_mrb,(MEMW m, FR r, double *bounds))
-LOWFUNC(NONE,READ,2,raw_fmovs_rm,(FW r, MEMR m))
+LOWFUNC(NONE,READ,2,raw_fmovs_rm,(FW r, MEMPTRR m))
{
raw_flds(m);
tos_make(r);
}
-LENDFUNC(NONE,READ,2,raw_fmovs_rm,(FW r, MEMR m))
-LOWFUNC(NONE,WRITE,2,raw_fmovs_mr,(MEMW m, FR r))
+LOWFUNC(NONE,WRITE,2,raw_fmovs_mr,(MEMPTRW m, FR r))
{
make_tos(r);
raw_fsts(m);
}
-LENDFUNC(NONE,WRITE,2,raw_fmovs_mr,(MEMW m, FR r))
-LOWFUNC(NONE,WRITE,2,raw_fmov_ext_mr,(MEMW m, FR r))
+LOWFUNC(NONE,WRITE,2,raw_fmov_ext_mr,(MEMPTRW m, FR r))
{
int rs;
raw_fstpt(m); /* store and pop it */
}
-LENDFUNC(NONE,WRITE,2,raw_fmov_ext_mr,(MEMW m, FR r))
-LOWFUNC(NONE,WRITE,2,raw_fmov_ext_mr_drop,(MEMW m, FR r))
+LOWFUNC(NONE,WRITE,2,raw_fmov_ext_mr_drop,(MEMPTRW m, FR r))
{
make_tos(r);
raw_fstpt(m); /* store and pop it */
live.tos--;
live.spos[r]=-2;
}
-LENDFUNC(NONE,WRITE,2,raw_fmov_ext_mr,(MEMW m, FR r))
-LOWFUNC(NONE,READ,2,raw_fmov_ext_rm,(FW r, MEMR m))
+LOWFUNC(NONE,READ,2,raw_fmov_ext_rm,(FW r, MEMPTRR m))
{
raw_fldt(m);
tos_make(r);
}
-LENDFUNC(NONE,READ,2,raw_fmov_ext_rm,(FW r, MEMR m))
LOWFUNC(NONE,NONE,1,raw_fmov_pi,(FW r))
{
emit_byte(0xeb);
tos_make(r);
}
-LENDFUNC(NONE,NONE,1,raw_fmov_pi,(FW r))
LOWFUNC(NONE,NONE,1,raw_fmov_log10_2,(FW r))
{
emit_byte(0xec);
tos_make(r);
}
-LENDFUNC(NONE,NONE,1,raw_fmov_log10_2,(FW r))
LOWFUNC(NONE,NONE,1,raw_fmov_log2_e,(FW r))
{
emit_byte(0xea);
tos_make(r);
}
-LENDFUNC(NONE,NONE,1,raw_fmov_log2_e,(FW r))
LOWFUNC(NONE,NONE,1,raw_fmov_loge_2,(FW r))
{
emit_byte(0xed);
tos_make(r);
}
-LENDFUNC(NONE,NONE,1,raw_fmov_loge_2,(FW r))
LOWFUNC(NONE,NONE,1,raw_fmov_1,(FW r))
{
emit_byte(0xe8);
tos_make(r);
}
-LENDFUNC(NONE,NONE,1,raw_fmov_1,(FW r))
LOWFUNC(NONE,NONE,1,raw_fmov_0,(FW r))
{
emit_byte(0xee);
tos_make(r);
}
-LENDFUNC(NONE,NONE,1,raw_fmov_0,(FW r))
LOWFUNC(NONE,NONE,2,raw_fmov_rr,(FW d, FR s))
{
tos_make(d); /* store to destination, pop if necessary */
}
}
-LENDFUNC(NONE,NONE,2,raw_fmov_rr,(FW d, FR s))
LOWFUNC(NONE,READ,2,raw_fldcw_m_indexed,(R4 index, IMM base))
{
emit_byte(0xa8 + index);
emit_long(base);
}
-LENDFUNC(NONE,READ,2,raw_fldcw_m_indexed,(R4 index, IMM base))
LOWFUNC(NONE,NONE,2,raw_fsqrt_rr,(FW d, FR s))
{
emit_byte(0xfa); /* take square root */
}
}
-LENDFUNC(NONE,NONE,2,raw_fsqrt_rr,(FW d, FR s))
LOWFUNC(NONE,NONE,2,raw_fabs_rr,(FW d, FR s))
{
emit_byte(0xe1); /* take fabs */
}
}
-LENDFUNC(NONE,NONE,2,raw_fabs_rr,(FW d, FR s))
LOWFUNC(NONE,NONE,2,raw_frndint_rr,(FW d, FR s))
{
emit_byte(0xfc); /* take frndint */
}
}
-LENDFUNC(NONE,NONE,2,raw_frndint_rr,(FW d, FR s))
LOWFUNC(NONE,NONE,2,raw_fcos_rr,(FW d, FR s))
{
emit_byte(0xff); /* take cos */
}
}
-LENDFUNC(NONE,NONE,2,raw_fcos_rr,(FW d, FR s))
LOWFUNC(NONE,NONE,2,raw_fsin_rr,(FW d, FR s))
{
emit_byte(0xfe); /* fsin y=sin(x) */
}
}
-LENDFUNC(NONE,NONE,2,raw_fsin_rr,(FW d, FR s))
static const double one = 1;
emit_byte(0xd9);
emit_byte(0xc0+ds); /* fld x */
emit_byte(0xd9);
+ emit_byte(0xc0); /* duplicate top of stack. Now up to 8 high */
+ emit_byte(0xd9);
emit_byte(0xfc); /* frndint int(x) */
emit_byte(0xd9);
- emit_byte(0xc1+ds); /* fld x again */
+ emit_byte(0xc9); /* swap top two elements */
emit_byte(0xd8);
emit_byte(0xe1); /* fsub frac(x) = x - int(x) */
emit_byte(0xd9);
emit_byte(0xd9); /* fstp copy & pop */
tos_make(d); /* store y=2^x */
}
-LENDFUNC(NONE,NONE,2,raw_ftwotox_rr,(FW d, FR s))
LOWFUNC(NONE,NONE,2,raw_fetox_rr,(FW d, FR s))
{
int ds;
- if (s==d)
- make_tos(s);
- else {
- ds=stackpos(s);
- emit_byte(0xd9);
- emit_byte(0xc0+ds); /* duplicate source */
- }
+ usereg(s);
+ ds=stackpos(s);
+ emit_byte(0xd9);
+ emit_byte(0xc0+ds); /* duplicate source */
emit_byte(0xd9);
emit_byte(0xea); /* fldl2e log2(e) */
- emit_byte(0xd8);
- emit_byte(0xc9); /* fmul x*log2(e) */
- emit_byte(0xdd);
- emit_byte(0xd1); /* fst copy up */
+ emit_byte(0xde);
+ emit_byte(0xc9); /* fmulp --- multiply source by log2(e) */
+
emit_byte(0xd9);
- emit_byte(0xfc); /* frndint int(x*log2(e)) */
+ emit_byte(0xc0); /* duplicate top of stack. Now up to 8 high */
emit_byte(0xd9);
- emit_byte(0xc9); /* fxch swap top two elements */
+ emit_byte(0xfc); /* rndint */
+ emit_byte(0xd9);
+ emit_byte(0xc9); /* swap top two elements */
emit_byte(0xd8);
- emit_byte(0xe1); /* fsub x*log2(e) - int(x*log2(e)) */
+ emit_byte(0xe1); /* subtract rounded from original */
emit_byte(0xd9);
- emit_byte(0xf0); /* f2xm1 (2^frac(x))-1 */
- x86_fadd_m((uintptr) &one); /* Add '1' without using extra stack space */
+ emit_byte(0xf0); /* f2xm1 */
+ x86_fadd_m((uintptr)&one); /* Add '1' without using extra stack space */
emit_byte(0xd9);
- emit_byte(0xfd); /* fscale (2^frac(x))*2^int(x*log2(e)) */
+ emit_byte(0xfd); /* and scale it */
emit_byte(0xdd);
- emit_byte(0xd9); /* fstp copy & pop */
- if (s!=d)
- tos_make(d); /* store y=e^x */
+ emit_byte(0xd9); /* take he rounded value off */
+ tos_make(d); /* store to destination */
}
-LENDFUNC(NONE,NONE,2,raw_fetox_rr,(FW d, FR s))
LOWFUNC(NONE,NONE,2,raw_flog2_rr,(FW d, FR s))
{
int ds;
- if (s==d)
- make_tos(s);
- else {
- ds=stackpos(s);
- emit_byte(0xd9);
- emit_byte(0xc0+ds); /* duplicate source */
- }
+ usereg(s);
+ ds=stackpos(s);
+ emit_byte(0xd9);
+ emit_byte(0xc0+ds); /* duplicate source */
emit_byte(0xd9);
emit_byte(0xe8); /* push '1' */
emit_byte(0xd9);
emit_byte(0xc9); /* swap top two */
emit_byte(0xd9);
emit_byte(0xf1); /* take 1*log2(x) */
- if (s!=d)
- tos_make(d); /* store to destination */
+ tos_make(d); /* store to destination */
}
-LENDFUNC(NONE,NONE,2,raw_flog2_rr,(FW d, FR s))
LOWFUNC(NONE,NONE,2,raw_fneg_rr,(FW d, FR s))
emit_byte(0xe0); /* take fchs */
}
}
-LENDFUNC(NONE,NONE,2,raw_fneg_rr,(FW d, FR s))
LOWFUNC(NONE,NONE,2,raw_fadd_rr,(FRW d, FR s))
{
emit_byte(0xc0+ds); /* add source to dest*/
}
}
-LENDFUNC(NONE,NONE,2,raw_fadd_rr,(FRW d, FR s))
LOWFUNC(NONE,NONE,2,raw_fsub_rr,(FRW d, FR s))
{
emit_byte(0xe0+ds); /* sub src from dest */
}
}
-LENDFUNC(NONE,NONE,2,raw_fsub_rr,(FRW d, FR s))
LOWFUNC(NONE,NONE,2,raw_fcmp_rr,(FR d, FR s))
{
emit_byte(0xdd);
emit_byte(0xe0+ds); /* cmp dest with source*/
}
-LENDFUNC(NONE,NONE,2,raw_fcmp_rr,(FR d, FR s))
LOWFUNC(NONE,NONE,2,raw_fmul_rr,(FRW d, FR s))
{
emit_byte(0xc8+ds); /* mul dest by source*/
}
}
-LENDFUNC(NONE,NONE,2,raw_fmul_rr,(FRW d, FR s))
LOWFUNC(NONE,NONE,2,raw_fdiv_rr,(FRW d, FR s))
{
emit_byte(0xf0+ds); /* div dest by source*/
}
}
-LENDFUNC(NONE,NONE,2,raw_fdiv_rr,(FRW d, FR s))
LOWFUNC(NONE,NONE,2,raw_frem_rr,(FRW d, FR s))
{
emit_byte(0xd9);
emit_byte(0xf8); /* take rem from dest by source */
}
-LENDFUNC(NONE,NONE,2,raw_frem_rr,(FRW d, FR s))
LOWFUNC(NONE,NONE,2,raw_frem1_rr,(FRW d, FR s))
{
emit_byte(0xd9);
emit_byte(0xf5); /* take rem1 from dest by source */
}
-LENDFUNC(NONE,NONE,2,raw_frem1_rr,(FRW d, FR s))
LOWFUNC(NONE,NONE,1,raw_ftst_r,(FR r))
emit_byte(0xd9); /* ftst */
emit_byte(0xe4);
}
-LENDFUNC(NONE,NONE,1,raw_ftst_r,(FR r))
LOWFUNC(NONE,NONE,2,raw_fetoxM1_rr,(FW d, FR s))
{
emit_byte(0xe1); /* fsub x*log2(e) - int(x*log2(e)) */
emit_byte(0xd9);
emit_byte(0xf0); /* f2xm1 (2^frac(x))-1 */
- emit_byte(0xd8);
- emit_byte(0x05);
- emit_long((uae_u32)&one); /* fadd (2^frac(x))-1 + 1 */
emit_byte(0xd9);
- emit_byte(0xfd); /* fscale ((2^frac(x)))*2^int(x*log2(e)) */
+ emit_byte(0xfd); /* fscale ((2^frac(x))-1)*2^int(x*log2(e)) */
emit_byte(0xdd);
emit_byte(0xd9); /* fstp copy & pop */
- emit_byte(0xd8);
- emit_byte(0x25);
- emit_long((uae_u32)&one); /* fsub 1 */
if (s!=d)
tos_make(d); /* store y=(e^x)-1 */
}
-LENDFUNC(NONE,NONE,2,raw_fetoxM1_rr,(FW d, FR s))
LOWFUNC(NONE,NONE,2,raw_ftentox_rr,(FW d, FR s))
{
if (s!=d)
tos_make(d); /* store y=10^x */
}
-LENDFUNC(NONE,NONE,2,raw_ftentox_rr,(FW d, FR s))
LOWFUNC(NONE,NONE,3,raw_fsincos_rr,(FW d, FW c, FR s))
{
tos_make(d); /* store sin(x) to destination */
}
}
-LENDFUNC(NONE,NONE,3,raw_fsincos_rr,(FW d, FW c, FR s))
LOWFUNC(NONE,NONE,2,raw_fscale_rr,(FRW d, FR s))
{
tos_make(d); /* store y=y*(2^x) */
}
}
-LENDFUNC(NONE,NONE,2,raw_fscale_rr,(FRW d, FR s))
LOWFUNC(NONE,NONE,2,raw_ftan_rr,(FW d, FR s))
{
emit_byte(0xd8); /* fstp pop 1.0 */
}
}
-LENDFUNC(NONE,NONE,2,raw_ftan_rr,(FW d, FR s))
#ifdef CPU_x86_64
#define REX64() emit_byte(0x48)
emit_byte(0xc4);
emit_byte(0x04); /* add +4 to esp */
}
-LENDFUNC(NONE,NONE,1,raw_fcuts_r,(FRW r))
LOWFUNC(NONE,NONE,1,raw_fcut_r,(FRW r))
{
emit_byte(0xc4);
emit_byte(0x08); /* add +8 to esp */
}
-LENDFUNC(NONE,NONE,1,raw_fcut_r,(FRW r))
LOWFUNC(NONE,NONE,2,raw_fgetexp_rr,(FW d, FR s))
{
emit_byte(0xd8); /* fstp just pop man */
}
}
-LENDFUNC(NONE,NONE,2,raw_fgetexp_rr,(FW d, FR s))
LOWFUNC(NONE,NONE,2,raw_fgetman_rr,(FW d, FR s))
{
emit_byte(0xd9); /* fstp copy man up & pop */
}
}
-LENDFUNC(NONE,NONE,2,raw_fgetman_rr,(FW d, FR s))
LOWFUNC(NONE,NONE,2,raw_flogN_rr,(FW d, FR s))
{
if (s!=d)
tos_make(d); /* store y=logN(x) */
}
-LENDFUNC(NONE,NONE,2,raw_flogN_rr,(FW d, FR s))
LOWFUNC(NONE,NONE,2,raw_flogNP1_rr,(FW d, FR s))
{
if (s!=d)
tos_make(d); /* store y=logN(x+1) */
}
-LENDFUNC(NONE,NONE,2,raw_flogNP1_rr,(FW d, FR s))
LOWFUNC(NONE,NONE,2,raw_flog10_rr,(FW d, FR s))
{
if (s!=d)
tos_make(d); /* store y=log10(x) */
}
-LENDFUNC(NONE,NONE,2,raw_flog10_rr,(FW d, FR s))
LOWFUNC(NONE,NONE,2,raw_fasin_rr,(FW d, FR s))
{
emit_byte(0xf3); /* fpatan atan(x/sqrt(1-(x^2))) & pop */
tos_make(d); /* store y=asin(x) */
}
-LENDFUNC(NONE,NONE,2,raw_fasin_rr,(FW d, FR s))
-static uae_u32 pihalf[] = {0x2168c235, 0xc90fdaa2, 0x3fff};
+static uae_u32 const pihalf[] = {0x2168c234, 0xc90fdaa2, 0x3fff}; // LSB=0 to get acos(1)=0
LOWFUNC(NONE,NONE,2,raw_facos_rr,(FW d, FR s))
{
emit_byte(0xe1); /* fsubrp pi/2 - asin(x) & pop */
tos_make(d); /* store y=acos(x) */
}
-LENDFUNC(NONE,NONE,2,raw_facos_rr,(FW d, FR s))
LOWFUNC(NONE,NONE,2,raw_fatan_rr,(FW d, FR s))
{
if (s!=d)
tos_make(d); /* store y=atan(x) */
}
-LENDFUNC(NONE,NONE,2,raw_fatan_rr,(FW d, FR s))
LOWFUNC(NONE,NONE,2,raw_fatanh_rr,(FW d, FR s))
{
emit_byte(0xde);
emit_byte(0xf9); /* fdivp (1+x)/(1-x) */
emit_byte(0xd9);
- emit_byte(0xed); /* fldln2 logN(2) */
+ emit_byte(0xed); /* fldl2e logN(2) */
emit_byte(0xd9);
emit_byte(0xc9); /* fxch swap logN(2) with (1+x)/(1-x) */
emit_byte(0xd9);
emit_byte(0xd9); /* fstp copy & pop */
tos_make(d); /* store y=atanh(x) */
}
-LENDFUNC(NONE,NONE,2,raw_fatanh_rr,(FW d, FR s))
LOWFUNC(NONE,NONE,2,raw_fsinh_rr,(FW d, FR s))
{
if (s!=d)
tos_make(d); /* store y=sinh(x) */
}
-LENDFUNC(NONE,NONE,2,raw_fsinh_rr,(FW d, FR s))
LOWFUNC(NONE,NONE,2,raw_fcosh_rr,(FW d, FR s))
{
if (s!=d)
tos_make(d); /* store y=cosh(x) */
}
-LENDFUNC(NONE,NONE,2,raw_fcosh_rr,(FW d, FR s))
LOWFUNC(NONE,NONE,2,raw_ftanh_rr,(FW d, FR s))
{
if (s!=d)
tos_make(d); /* store y=tanh(x) */
}
-LENDFUNC(NONE,NONE,2,raw_ftanh_rr,(FW d, FR s))
/* %eax register is clobbered if target processor doesn't support fucomi */
#define FFLAG_NREG_CLOBBER_CONDITION !have_cmov
/* --- 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) ? \
/* _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) ))
#ifdef UAE
#ifdef CPU_64_BIT
typedef uae_u64 uintptr;
+typedef uae_s64 intptr;
#else
typedef uae_u32 uintptr;
#endif
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)
/* 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);
uae_u8 needflush;
} freg_status;
+#define SP_REG 15
#define PC_P 16
#define FLAGX 17
#define FLAGTMP 18
#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
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)))
#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
/* 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
/*
- * UAE - The Un*x Amiga Emulator
- *
- * MC68881 emulation
- *
- * Copyright 1996 Herman ten Brugge
- * Adapted for JIT compilation (c) Bernd Meyer, 2000
- * Modified 2005 Peter Keunecke
- */
-
-#include "sysconfig.h"
+ * compiler/compemu_fpp.cpp - Dynamic translation of FPU instructions
+ *
+ * Copyright (c) 2001-2004 Milan Jurik of ARAnyM dev team (see AUTHORS)
+ *
+ * Inspired by Christian Bauer's Basilisk II
+ *
+ * This file is part of the ARAnyM project which builds a new and powerful
+ * TOS/FreeMiNT compatible virtual machine running on almost any hardware.
+ *
+ * JIT compiler m68k -> IA-32 and AMD64
+ *
+ * Original 68040 JIT compiler for UAE, copyright 2000-2002 Bernd Meyer
+ * Adaptation for Basilisk II and improvements, copyright 2000-2004 Gwenole Beauchesne
+ * Portions related to CPU detection come from linux/arch/i386/kernel/setup.c
+ *
+ * ARAnyM is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * ARAnyM is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with ARAnyM; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+/*
+ * UAE - The Un*x Amiga Emulator
+ *
+ * MC68881 emulation
+ *
+ * Copyright 1996 Herman ten Brugge
+ * Adapted for JIT compilation (c) Bernd Meyer, 2000
+ */
+
#include "sysdeps.h"
-#include "options.h"
-#include "memory.h"
-#include "custom.h"
+#include <cmath>
+#include <cstdio>
+#include <cassert>
+
+#include "memory-uae.h"
+#include "readcpu.h"
#include "newcpu.h"
-#include "ersatz.h"
-#include "md-fpp.h"
#include "compemu.h"
+//#include "fpu/fpu.h"
+//#include "fpu/flags.h"
+//#include "fpu/exceptions.h"
+//#include "fpu/rounding.h"
-#if defined(JIT)
-uae_u32 temp_fp[] = { 0, 0, 0 }; /* To convert between FP and <EA> */
+#define DEBUG 0
+#include "debug.h"
-/* 128 words, indexed through the low byte of the 68k fpu control word */
-static const uae_u16 x86_fpucw[] = {
- 0x137f, 0x137f, 0x137f, 0x137f, 0x137f, 0x137f, 0x137f, 0x137f, /* E-RN */
- 0x1f7f, 0x1f7f, 0x1f7f, 0x1f7f, 0x1f7f, 0x1f7f, 0x1f7f, 0x1f7f, /* E-RZ */
- 0x177f, 0x177f, 0x177f, 0x177f, 0x177f, 0x177f, 0x177f, 0x177f, /* E-RD */
- 0x1b7f, 0x1b7f, 0x1b7f, 0x1b7f, 0x1b7f, 0x1b7f, 0x1b7f, 0x1b7f, /* E-RU */
-
- 0x107f, 0x107f, 0x107f, 0x107f, 0x107f, 0x107f, 0x107f, 0x107f, /* S-RN */
- 0x1c7f, 0x1c7f, 0x1c7f, 0x1c7f, 0x1c7f, 0x1c7f, 0x1c7f, 0x1c7f, /* S-RZ */
- 0x147f, 0x147f, 0x147f, 0x147f, 0x147f, 0x147f, 0x147f, 0x147f, /* S-RD */
- 0x187f, 0x187f, 0x187f, 0x187f, 0x187f, 0x187f, 0x187f, 0x187f, /* S-RU */
-
- 0x127f, 0x127f, 0x127f, 0x127f, 0x127f, 0x127f, 0x127f, 0x127f, /* D-RN */
- 0x1e7f, 0x1e7f, 0x1e7f, 0x1e7f, 0x1e7f, 0x1e7f, 0x1e7f, 0x1e7f, /* D-RZ */
- 0x167f, 0x167f, 0x167f, 0x167f, 0x167f, 0x167f, 0x167f, 0x167f, /* D-RD */
- 0x1a7f, 0x1a7f, 0x1a7f, 0x1a7f, 0x1a7f, 0x1a7f, 0x1a7f, 0x1a7f, /* D-RU */
-
- 0x137f, 0x137f, 0x137f, 0x137f, 0x137f, 0x137f, 0x137f, 0x137f, /* ?-RN */
- 0x1f7f, 0x1f7f, 0x1f7f, 0x1f7f, 0x1f7f, 0x1f7f, 0x1f7f, 0x1f7f, /* ?-RZ */
- 0x177f, 0x177f, 0x177f, 0x177f, 0x177f, 0x177f, 0x177f, 0x177f, /* ?-RD */
- 0x1b7f, 0x1b7f, 0x1b7f, 0x1b7f, 0x1b7f, 0x1b7f, 0x1b7f, 0x1b7f /* ?-RU */
-};
-static const int sz1[8] = { 4, 4, 12, 12, 2, 8, 1, 0 };
-static const int sz2[8] = { 4, 4, 12, 12, 2, 8, 2, 0 };
-
-static struct {
- double b[2];
- double w[2];
- double l[2];
-} clamp_bounds = {
- { -128.0, 127.0 },
- { -32768.0, 32767.0 },
- { -2147483648.0, 2147483647.0 }
-};
+struct jit_disable_opcodes jit_disable;
+
+#if defined(USE_LONG_DOUBLE) || defined(USE_QUAD_DOUBLE)
+#define LD(x) x ## L
+#else
+#define LD(x) x
+#endif
+
+// gb-- WARNING: get_fpcr() and set_fpcr() support is experimental
+#define HANDLE_FPCR 0
+
+// - IEEE-based fpu core must be used
+#if defined(FPU_IEEE)
+# define CAN_HANDLE_FPCR
+#endif
+
+// - Generic rounding mode and precision modes are supported if set together
+#if defined(FPU_USE_GENERIC_ROUNDING_MODE) && defined(FPU_USE_GENERIC_ROUNDING_PRECISION)
+# define CAN_HANDLE_FPCR
+#endif
+
+// - X86 rounding mode and precision modes are *not* supported but might work (?!)
+#if defined(FPU_USE_X86_ROUNDING_MODE) && defined(FPU_USE_X86_ROUNDING_PRECISION)
+# define CAN_HANDLE_FPCR
+#endif
-/* return the required floating point precision or -1 for failure, 0=E, 1=S, 2=D */
-STATIC_INLINE int comp_fp_get (uae_u32 opcode, uae_u16 extra, int treg)
+#if HANDLE_FPCR && !defined(CAN_HANDLE_FPCR)
+# warning "Can't handle FPCR, will FAIL(1) at runtime"
+# undef HANDLE_FPCR
+# define HANDLE_FPCR 0
+#endif
+
+//#define STATIC_INLINE static inline
+#define MAKE_FPSR(r) do { fmov_rr(FP_RESULT,r); } while (0)
+
+#define delay nop() ;nop()
+#define delay2 nop() ;nop()
+
+#define UNKNOWN_EXTRA 0xFFFFFFFF
+#if 0
+static void fpuop_illg(uae_u32 opcode, uae_u32 /* extra */)
{
- int reg = opcode & 7;
- int mode = (opcode >> 3) & 7;
- int size = (extra >> 10) & 7;
+/*
+ if (extra == UNKNOWN_EXTRA)
+ printf("FPU opcode %x, extra UNKNOWN_EXTRA\n",opcode & 0xFFFF);
+ else
+ printf("FPU opcode %x, extra %x\n",opcode & 0xFFFF,extra & 0xFFFF);
+*/
+ op_illg(opcode);
+}
+#endif
- if (size == 3 || size == 7) /* 3 = packed decimal, 7 is not defined */
- return -1;
- switch (mode) {
- case 0: /* Dn */
- switch (size) {
- case 0: /* Long */
- mov_l_mr (uae_p32(temp_fp), reg);
- fmovi_rm (treg, uae_p32(temp_fp));
- return 2;
- case 1: /* Single */
- mov_l_mr (uae_p32(temp_fp), reg);
- fmovs_rm (treg, uae_p32(temp_fp));
- return 1;
- case 4: /* Word */
- sign_extend_16_rr (S1, reg);
- mov_l_mr (uae_p32(temp_fp), S1);
- fmovi_rm (treg, uae_p32(temp_fp));
- return 1;
- case 6: /* Byte */
- sign_extend_8_rr (S1, reg);
- mov_l_mr (uae_p32(temp_fp), S1);
- fmovi_rm (treg, uae_p32(temp_fp));
- return 1;
- default:
+uae_s32 temp_fp[4]; /* To convert between FP/integer */
+
+/* return register number, or -1 for failure */
+STATIC_INLINE int get_fp_value(uae_u32 opcode, uae_u16 extra)
+{
+ int size;
+ int mode;
+ int reg;
+ uae_u32 ad = 0;
+ static int const sz1[8] = { 4, 4, 12, 12, 2, 8, 1, 0 };
+ static int const sz2[8] = { 4, 4, 12, 12, 2, 8, 2, 0 };
+
+ if ((extra & 0x4000) == 0)
+ {
+ return ((extra >> 10) & 7);
+ }
+
+ mode = (opcode >> 3) & 7;
+ reg = opcode & 7;
+ size = (extra >> 10) & 7;
+ switch (mode)
+ {
+ case 0: /* Dn */
+ switch (size)
+ {
+ case 6: /* byte */
+ sign_extend_8_rr(S1, reg);
+ mov_l_mr((uintptr) temp_fp, S1);
+ delay2;
+ fmovi_rm(FS1, (uintptr) temp_fp);
+ return FS1;
+ case 4: /* word */
+ sign_extend_16_rr(S1, reg);
+ mov_l_mr((uintptr) temp_fp, S1);
+ delay2;
+ fmovi_rm(FS1, (uintptr) temp_fp);
+ return FS1;
+ case 0: /* long */
+ mov_l_mr((uintptr) temp_fp, reg);
+ delay2;
+ fmovi_rm(FS1, (uintptr) temp_fp);
+ return FS1;
+ case 1: /* single precision */
+ mov_l_mr((uintptr) temp_fp, reg);
+ delay2;
+ fmovs_rm(FS1, (uintptr) temp_fp);
+ return FS1;
+ default:
return -1;
}
- case 1: /* An, invalid mode */
+ return -1; /* Should be unreachable */
+ case 1: /* An */
+ return -1; /* Genuine invalid instruction */
+ default:
+ break;
+ }
+
+ /* OK, we *will* have to load something from an address. Let's make
+ sure we know how to handle that, or quit early --- i.e. *before*
+ we do any postincrement/predecrement that we may regret */
+ switch (size)
+ {
+ case 0: /* long */
+ case 1: /* single precision */
+ case 2: /* extended precision */
+ case 4: /* word */
+ case 5: /* double precision */
+ case 6: /* byte */
+ break;
+ case 3: /* packed decimal static */
+ default:
return -1;
- case 2: /* (An) */
- mov_l_rr (S1, reg + 8);
+ }
+
+ switch (mode)
+ {
+ case 2: /* (An) */
+ ad = S1; /* We will change it, anyway ;-) */
+ mov_l_rr(ad, reg + 8);
break;
- case 3: /* (An)+ */
- mov_l_rr (S1, reg + 8);
- lea_l_brr (reg + 8, reg + 8, (reg == 7 ? sz2[size] : sz1[size]));
+ case 3: /* (An)+ */
+ ad = S1;
+ mov_l_rr(ad, reg + 8);
+ lea_l_brr(reg + 8, reg + 8, (reg == 7 ? sz2[size] : sz1[size]));
break;
- case 4: /* -(An) */
- lea_l_brr (reg + 8, reg + 8, -(reg == 7 ? sz2[size] : sz1[size]));
- mov_l_rr (S1, reg + 8);
+ case 4: /* -(An) */
+ ad = S1;
+ lea_l_brr(reg + 8, reg + 8, -(reg == 7 ? sz2[size] : sz1[size]));
+ mov_l_rr(ad, reg + 8);
break;
- case 5: /* (d16,An) */
+ case 5: /* d16(An) */
{
- uae_u32 off = (uae_s32) (uae_s16) comp_get_iword ((m68k_pc_offset += 2) - 2);
- mov_l_rr (S1, reg + 8);
- lea_l_brr (S1, S1, off);
- break;
+ uae_u32 off = (uae_s32) (uae_s16) comp_get_iword((m68k_pc_offset += 2) - 2);
+
+ ad = S1;
+ mov_l_rr(ad, reg + 8);
+ lea_l_brr(ad, ad, off);
}
- case 6: /* (d8,An,Xn) or (bd,An,Xn) or ([bd,An,Xn],od) or ([bd,An],Xn,od) */
+ break;
+ case 6: /* d8(An,Xn) */
{
- uae_u32 dp = comp_get_iword ((m68k_pc_offset += 2) - 2);
- calc_disp_ea_020 (reg + 8, dp, S1, S2);
- break;
+ uae_u32 dp = comp_get_iword((m68k_pc_offset += 2) - 2);
+
+ ad = S1;
+ calc_disp_ea_020(reg + 8, dp, ad, S2);
}
- case 7:
- switch (reg) {
- case 0: /* (xxx).W */
+ break;
+ case 7:
+ switch (reg)
+ {
+ case 0: /* abs.w */
{
- uae_u32 off = (uae_s32) (uae_s16) comp_get_iword ((m68k_pc_offset += 2) - 2);
- mov_l_ri (S1, off);
- break;
+ uae_u32 off = (uae_s32) (uae_s16) comp_get_iword((m68k_pc_offset += 2) - 2);
+
+ ad = S1;
+ mov_l_ri(ad, off);
}
- case 1: /* (xxx).L */
+ break;
+ case 1: /* abs.l */
{
- uae_u32 off = comp_get_ilong ((m68k_pc_offset += 4) - 4);
- mov_l_ri (S1, off);
- break;
+ uae_u32 off = comp_get_ilong((m68k_pc_offset += 4) - 4);
+
+ ad = S1;
+ mov_l_ri(ad, off);
}
- case 2: /* (d16,PC) */
+ break;
+ case 2: /* d16(pc) */
{
- uae_u32 address = start_pc + ((uae_char*) comp_pc_p - (uae_char*) start_pc_p) + m68k_pc_offset;
- uae_s32 PC16off = (uae_s32) (uae_s16) comp_get_iword ((m68k_pc_offset += 2) - 2);
- mov_l_ri (S1, address + PC16off);
- break;
+ uae_u32 address = start_pc + ((char *) comp_pc_p - (char *) start_pc_p) + m68k_pc_offset;
+ uae_s32 PC16off = (uae_s32) (uae_s16) comp_get_iword((m68k_pc_offset += 2) - 2);
+
+ ad = S1;
+ mov_l_ri(ad, address + PC16off);
}
- case 3: /* (d8,PC,Xn) or (bd,PC,Xn) or ([bd,PC,Xn],od) or ([bd,PC],Xn,od) */
+ break;
+ case 3: /* d8(pc,Xn) */
+ return -1;
+ case 4: /* #imm */
{
- uae_u32 address = start_pc + ((uae_char*)comp_pc_p - (uae_char*)start_pc_p) + m68k_pc_offset;
- uae_u32 dp = comp_get_iword((m68k_pc_offset += 2) - 2);
- mov_l_ri(S3, address);
- calc_disp_ea_020(S3, dp, S1, S2);
- break;
- }
- case 4: /* # < data >; Constants should be converted just once by the JIT */
- m68k_pc_offset += sz2[size];
- switch (size) {
- case 0:
- {
- uae_s32 li = comp_get_ilong(m68k_pc_offset - 4);
- float si = (float)li;
-
- if (li == (int)si) {
- //write_log ("converted immediate LONG constant to SINGLE\n");
- mov_l_mi(uae_p32(temp_fp), *(uae_u32 *)&si);
- fmovs_rm(treg, uae_p32(temp_fp));
- return 1;
- }
- //write_log ("immediate LONG constant\n");
- mov_l_mi(uae_p32(temp_fp), *(uae_u32 *)&li);
- fmovi_rm(treg, uae_p32(temp_fp));
- return 2;
- }
- case 1:
- //write_log (_T("immediate SINGLE constant\n"));
- mov_l_mi(uae_p32(temp_fp), comp_get_ilong(m68k_pc_offset - 4));
- fmovs_rm(treg, uae_p32(temp_fp));
- return 1;
- case 2:
- //write_log (_T("immediate LONG DOUBLE constant\n"));
- mov_l_mi(uae_p32(temp_fp), comp_get_ilong(m68k_pc_offset - 4));
- mov_l_mi((uae_p32(temp_fp)) + 4, comp_get_ilong(m68k_pc_offset - 8));
- mov_l_mi((uae_p32(temp_fp)) + 8, (uae_u32)comp_get_iword(m68k_pc_offset - 12));
- fmov_ext_rm(treg, uae_p32(temp_fp));
- return 0;
- case 4:
- {
- float si = (float)(uae_s16)comp_get_iword(m68k_pc_offset-2);
-
- //write_log (_T("converted immediate WORD constant %f to SINGLE\n"), si);
- mov_l_mi(uae_p32(temp_fp),*(uae_u32 *)&si);
- fmovs_rm(treg,uae_p32(temp_fp));
- return 1;
- }
- case 5:
- {
- uae_u32 longarray[] = { comp_get_ilong(m68k_pc_offset - 4),
- comp_get_ilong(m68k_pc_offset - 8) };
- float si = (float)*(double *)longarray;
-
- if (*(double *)longarray == (double)si) {
- //write_log (_T("SPEED GAIN: converted a DOUBLE constant to SINGLE\n"));
- mov_l_mi(uae_p32(temp_fp), *(uae_u32 *)&si);
- fmovs_rm(treg, uae_p32(temp_fp));
- return 1;
- }
- //write_log (_T("immediate DOUBLE constant\n"));
- mov_l_mi(uae_p32(temp_fp), longarray[0]);
- mov_l_mi((uae_p32(temp_fp)) + 4, longarray[1]);
- fmov_rm(treg, uae_p32(temp_fp));
- return 2;
- }
- case 6:
- {
- float si = (float)(uae_s8)comp_get_ibyte(m68k_pc_offset - 2);
+ uae_u32 address = start_pc + ((char *) comp_pc_p - (char *) start_pc_p) + m68k_pc_offset;
- //write_log (_T("converted immediate BYTE constant to SINGLE\n"));
- mov_l_mi(uae_p32(temp_fp), *(uae_u32 *)&si);
- fmovs_rm(treg, uae_p32(temp_fp));
- return 1;
- }
- default: /* never reached */
- return -1;
+ ad = S1;
+ // Immediate addressing mode && Operation Length == Byte ->
+ // Use the low-order byte of the extension word.
+ if (size == 6)
+ address++;
+ mov_l_ri(ad, address);
+ m68k_pc_offset += sz2[size];
}
- default: /* never reached */
+ break;
+ default:
return -1;
}
}
- switch (size) {
- case 0: /* Long */
- readlong (S1, S2, S3);
- mov_l_mr (uae_p32(temp_fp), S2);
- fmovi_rm (treg, uae_p32(temp_fp));
- return 2;
- case 1: /* Single */
- readlong (S1, S2, S3);
- mov_l_mr (uae_p32(temp_fp), S2);
- fmovs_rm (treg, uae_p32(temp_fp));
- return 1;
- case 2: /* Long Double */
- readword (S1, S2, S3);
- mov_w_mr ((uae_p32(temp_fp)) + 8, S2);
- add_l_ri (S1, 4);
- readlong (S1, S2, S3);
- mov_l_mr ((uae_p32(temp_fp)) + 4, S2);
- add_l_ri (S1, 4);
- readlong (S1, S2, S3);
- mov_l_mr ((uae_p32(temp_fp)), S2);
- fmov_ext_rm (treg, uae_p32(temp_fp));
- return 0;
- case 4: /* Word */
- readword (S1, S2, S3);
- sign_extend_16_rr (S2, S2);
- mov_l_mr (uae_p32(temp_fp), S2);
- fmovi_rm (treg, uae_p32(temp_fp));
- return 1;
- case 5: /* Double */
- readlong (S1, S2, S3);
- mov_l_mr ((uae_p32(temp_fp)) + 4, S2);
- add_l_ri (S1, 4);
- readlong (S1, S2, S3);
- mov_l_mr ((uae_p32(temp_fp)), S2);
- fmov_rm (treg, uae_p32(temp_fp));
- return 2;
- case 6: /* Byte */
- readbyte (S1, S2, S3);
- sign_extend_8_rr (S2, S2);
- mov_l_mr (uae_p32(temp_fp), S2);
- fmovi_rm (treg, uae_p32(temp_fp));
- return 1;
- default:
+ switch (size)
+ {
+ case 0: /* long */
+ readlong(ad, S2, S3);
+ mov_l_mr((uintptr) temp_fp, S2);
+ delay2;
+ fmovi_rm(FS1, (uintptr) temp_fp);
+ break;
+ case 1: /* single precision */
+ readlong(ad, S2, S3);
+ mov_l_mr((uintptr) temp_fp, S2);
+ delay2;
+ fmovs_rm(FS1, (uintptr) temp_fp);
+ break;
+ case 2: /* extended precision */
+ readword(ad, S2, S3);
+ mov_w_mr(((uintptr) temp_fp) + 8, S2);
+ add_l_ri(ad, 4);
+ readlong(ad, S2, S3);
+ // always set the explicit integer bit.
+ or_l_ri(S2, 0x80000000);
+ mov_l_mr((uintptr) (temp_fp) + 4, S2);
+ add_l_ri(ad, 4);
+ readlong(ad, S2, S3);
+ mov_l_mr((uintptr) (temp_fp), S2);
+ delay2;
+ fmov_ext_rm(FS1, (uintptr) (temp_fp));
+ break;
+ case 3: /* packed decimal static */
+ return -1; /* Some silly "packed" stuff */
+ case 4: /* word */
+ readword(ad, S2, S3);
+ sign_extend_16_rr(S2, S2);
+ mov_l_mr((uintptr) temp_fp, S2);
+ delay2;
+ fmovi_rm(FS1, (uintptr) temp_fp);
+ break;
+ case 5: /* double precision */
+ readlong(ad, S2, S3);
+ mov_l_mr(((uintptr) temp_fp) + 4, S2);
+ add_l_ri(ad, 4);
+ readlong(ad, S2, S3);
+ mov_l_mr((uintptr) (temp_fp), S2);
+ delay2;
+ fmov_rm(FS1, (uintptr) (temp_fp));
+ break;
+ case 6: /* byte */
+ readbyte(ad, S2, S3);
+ sign_extend_8_rr(S2, S2);
+ mov_l_mr((uintptr) temp_fp, S2);
+ delay2;
+ fmovi_rm(FS1, (uintptr) temp_fp);
+ break;
+ default:
return -1;
}
- return -1;
+ return FS1;
}
+
/* return of -1 means failure, >=0 means OK */
-STATIC_INLINE int comp_fp_put (uae_u32 opcode, uae_u16 extra)
+STATIC_INLINE int put_fp_value(int val, uae_u32 opcode, uae_u16 extra)
{
- int reg = opcode & 7;
- int sreg = (extra >> 7) & 7;
- int mode = (opcode >> 3) & 7;
- int size = (extra >> 10) & 7;
+ int size;
+ int mode;
+ int reg;
+ uae_u32 ad;
+ static int const sz1[8] = { 4, 4, 12, 12, 2, 8, 1, 0 };
+ static int const sz2[8] = { 4, 4, 12, 12, 2, 8, 2, 0 };
- if (size == 3 || size == 7) /* 3 = packed decimal, 7 is not defined */
- return -1;
- switch (mode) {
- case 0: /* Dn */
- switch (size) {
- case 0: /* FMOVE.L FPx, Dn */
-#if USE_X86_FPUCW && 0
- if (!(regs.fpcr & 0xf0)) { /* if extended round to nearest */
- mov_l_ri(S1,0x10); /* use extended round to zero mode */
- fldcw_m_indexed(S1,(uae_u32)x86_fpucw);
- fmovi_mrb(uae_p32(temp_fp),sreg, clamp_bounds.l);
- mov_l_rm(reg,uae_p32(temp_fp));
- mov_l_rm(S1,(uae_u32)®s.fpcr);
- and_l_ri(S1,0xf0); /* restore control word */
- fldcw_m_indexed(S1,(uae_u32)x86_fpucw);
- return 0;
- }
-#endif
- fmovi_mrb (uae_p32(temp_fp), sreg, clamp_bounds.l);
- mov_l_rm (reg, uae_p32(temp_fp));
+ if ((extra & 0x4000) == 0)
+ {
+ const int dest_reg = (extra >> 10) & 7;
+
+ fmov_rr(dest_reg, val);
+ // gb-- status register is affected
+ MAKE_FPSR(dest_reg);
+ return 0;
+ }
+
+ mode = (opcode >> 3) & 7;
+ reg = opcode & 7;
+ size = (extra >> 10) & 7;
+ ad = (uae_u32) -1;
+ switch (mode)
+ {
+ case 0: /* Dn */
+ switch (size)
+ {
+ case 6: /* byte */
+ fmovi_mr((uintptr) temp_fp, val);
+ delay;
+ mov_b_rm(reg, (uintptr) temp_fp);
return 0;
- case 1: /* FMOVE.S FPx, Dn */
- fmovs_mr (uae_p32(temp_fp), sreg);
- mov_l_rm (reg, uae_p32(temp_fp));
+ case 4: /* word */
+ fmovi_mr((uintptr) temp_fp, val);
+ delay;
+ mov_w_rm(reg, (uintptr) temp_fp);
return 0;
- case 4: /* FMOVE.W FPx, Dn */
-#if USE_X86_FPUCW && 0
- if (!(regs.fpcr & 0xf0)) { /* if extended round to nearest */
- mov_l_ri(S1,0x10); /* use extended round to zero mode */
- fldcw_m_indexed(S1,(uae_u32)x86_fpucw);
- fmovi_mrb(uae_p32(temp_fp),sreg, clamp_bounds.w);
- mov_w_rm(reg,uae_p32(temp_fp));
- mov_l_rm(S1,(uae_u32)®s.fpcr);
- and_l_ri(S1,0xf0); /* restore control word */
- fldcw_m_indexed(S1,(uae_u32)x86_fpucw);
- return 0;
- }
-#endif
- fmovi_mrb (uae_p32(temp_fp), sreg, clamp_bounds.w);
- mov_w_rm (reg, uae_p32(temp_fp));
+ case 0: /* long */
+ fmovi_mr((uintptr) temp_fp, val);
+ delay;
+ mov_l_rm(reg, (uintptr) temp_fp);
return 0;
- case 6: /* FMOVE.B FPx, Dn */
-#if USE_X86_FPUCW && 0
- if (!(regs.fpcr & 0xf0)) { /* if extended round to nearest */
- mov_l_ri(S1,0x10); /* use extended round to zero mode */
- fldcw_m_indexed(S1,(uae_u32)x86_fpucw);
- fmovi_mrb(uae_p32(temp_fp),sreg, clamp_bounds.b);
- mov_b_rm(reg,uae_p32(temp_fp));
- mov_l_rm(S1,(uae_u32)®s.fpcr);
- and_l_ri(S1,0xf0); /* restore control word */
- fldcw_m_indexed(S1,(uae_u32)x86_fpucw);
- return 0;
- }
-#endif
- fmovi_mrb (uae_p32(temp_fp), sreg, clamp_bounds.b);
- mov_b_rm (reg, uae_p32(temp_fp));
+ case 1: /* single precision */
+ fmovs_mr((uintptr) temp_fp, val);
+ delay;
+ mov_l_rm(reg, (uintptr) temp_fp);
return 0;
- default:
+ default:
return -1;
}
- case 1: /* An, invalid mode */
+ case 1: /* An */
+ return -1; /* genuine invalid instruction */
+ default:
+ break;
+ }
+
+ /* Let's make sure we get out *before* doing something silly if
+ we can't handle the size */
+ switch (size)
+ {
+ case 0: /* long */
+ case 1: /* single precision */
+ case 2: /* extended precision */
+ case 4: /* word */
+ case 5: /* double precision */
+ case 6: /* byte */
+ break;
+ case 3: /* packed decimal static */
+ default:
return -1;
- case 2: /* (An) */
- mov_l_rr (S1, reg + 8);
+ }
+
+ switch (mode)
+ {
+ case 2: /* (An) */
+ ad = S1;
+ mov_l_rr(ad, reg + 8);
break;
- case 3: /* (An)+ */
- mov_l_rr (S1, reg + 8);
- lea_l_brr (reg + 8, reg + 8, (reg == 7 ? sz2[size] : sz1[size]));
+ case 3: /* (An)+ */
+ ad = S1;
+ mov_l_rr(ad, reg + 8);
+ lea_l_brr(reg + 8, reg + 8, (reg == 7 ? sz2[size] : sz1[size]));
break;
- case 4: /* -(An) */
- lea_l_brr (reg + 8, reg + 8, -(reg == 7 ? sz2[size] : sz1[size]));
- mov_l_rr (S1, reg + 8);
+ case 4: /* -(An) */
+ ad = S1;
+ lea_l_brr(reg + 8, reg + 8, -(reg == 7 ? sz2[size] : sz1[size]));
+ mov_l_rr(ad, reg + 8);
break;
- case 5: /* (d16,An) */
+ case 5: /* d16(An) */
{
- uae_u32 off = (uae_s32) (uae_s16) comp_get_iword ((m68k_pc_offset += 2) - 2);
- mov_l_rr (S1, reg + 8);
- add_l_ri (S1, off);
- break;
+ uae_u32 off = (uae_s32) (uae_s16) comp_get_iword((m68k_pc_offset += 2) - 2);
+
+ ad = S1;
+ mov_l_rr(ad, reg + 8);
+ add_l_ri(ad, off);
}
- case 6: /* (d8,An,Xn) or (bd,An,Xn) or ([bd,An,Xn],od) or ([bd,An],Xn,od) */
+ break;
+ case 6: /* d8(An,Xn) */
{
- uae_u32 dp = comp_get_iword ((m68k_pc_offset += 2) - 2);
- calc_disp_ea_020 (reg + 8, dp, S1, S2);
- break;
+ uae_u32 dp = comp_get_iword((m68k_pc_offset += 2) - 2);
+
+ ad = S1;
+ calc_disp_ea_020(reg + 8, dp, ad, S2);
}
- case 7:
- switch (reg) {
- case 0: /* (xxx).W */
+ break;
+ case 7:
+ switch (reg)
+ {
+ case 0: /* abs.w */
{
- uae_u32 off = (uae_s32) (uae_s16) comp_get_iword ((m68k_pc_offset += 2) - 2);
- mov_l_ri (S1, off);
- break;
+ uae_u32 off = (uae_s32) (uae_s16) comp_get_iword((m68k_pc_offset += 2) - 2);
+
+ ad = S1;
+ mov_l_ri(ad, off);
}
- case 1: /* (xxx).L */
+ break;
+ case 1: /* abs.l */
{
- uae_u32 off = comp_get_ilong ((m68k_pc_offset += 4) - 4);
- mov_l_ri (S1, off);
- break;
+ uae_u32 off = comp_get_ilong((m68k_pc_offset += 4) - 4);
+
+ ad = S1;
+ mov_l_ri(ad, off);
+ }
+ break;
+ case 2: /* d16(pc) */
+ {
+ uae_u32 address = start_pc + ((char *) comp_pc_p - (char *) start_pc_p) + m68k_pc_offset;
+ uae_s32 PC16off = (uae_s32) (uae_s16) comp_get_iword((m68k_pc_offset += 2) - 2);
+
+ ad = S1;
+ mov_l_ri(ad, address + PC16off);
+ }
+ break;
+ case 3: /* d8(pc,Xn) */
+ return -1;
+ case 4: /* #imm */
+ {
+ uae_u32 address = start_pc + ((char *) comp_pc_p - (char *) start_pc_p) + m68k_pc_offset;
+
+ ad = S1;
+ mov_l_ri(ad, address);
+ m68k_pc_offset += sz2[size];
}
- default: /* All other modes are not allowed for FPx to <EA> */
- write_log (_T ("JIT FMOVE FPx,<EA> Mode is not allowed %04x %04x\n"), opcode, extra);
+ break;
+ default:
return -1;
}
}
- switch (size) {
- case 0: /* Long */
- fmovi_mrb (uae_p32(temp_fp), sreg, clamp_bounds.l);
- mov_l_rm (S2, uae_p32(temp_fp));
- writelong_clobber (S1, S2, S3);
- return 0;
- case 1: /* Single */
- fmovs_mr (uae_p32(temp_fp), sreg);
- mov_l_rm (S2, uae_p32(temp_fp));
- writelong_clobber (S1, S2, S3);
- return 0;
- case 2:/* Long Double */
- fmov_ext_mr (uae_p32(temp_fp), sreg);
- mov_w_rm (S2, uae_p32(temp_fp) + 8);
- writeword_clobber (S1, S2, S3);
- add_l_ri (S1, 4);
- mov_l_rm (S2, uae_p32(temp_fp) + 4);
- writelong_clobber (S1, S2, S3);
- add_l_ri (S1, 4);
- mov_l_rm (S2, uae_p32(temp_fp));
- writelong_clobber (S1, S2, S3);
- return 0;
- case 4: /* Word */
- fmovi_mrb (uae_p32(temp_fp), sreg, clamp_bounds.w);
- mov_l_rm (S2, uae_p32(temp_fp));
- writeword_clobber (S1, S2, S3);
- return 0;
- case 5: /* Double */
- fmov_mr (uae_p32(temp_fp), sreg);
- mov_l_rm (S2, uae_p32(temp_fp) + 4);
- writelong_clobber (S1, S2, S3);
- add_l_ri (S1, 4);
- mov_l_rm (S2, uae_p32(temp_fp));
- writelong_clobber (S1, S2, S3);
- return 0;
- case 6: /* Byte */
- fmovi_mrb (uae_p32(temp_fp), sreg, clamp_bounds.b);
- mov_l_rm (S2, uae_p32(temp_fp));
- writebyte (S1, S2, S3);
- return 0;
- default:
+
+ switch (size)
+ {
+ case 0: /* long */
+ fmovi_mr((uintptr) temp_fp, val);
+ delay;
+ mov_l_rm(S2, (uintptr) temp_fp);
+ writelong_clobber(ad, S2, S3);
+ break;
+ case 1: /* single precision */
+ fmovs_mr((uintptr) temp_fp, val);
+ delay;
+ mov_l_rm(S2, (uintptr) temp_fp);
+ writelong_clobber(ad, S2, S3);
+ break;
+ case 2: /* extended precision */
+ fmov_ext_mr((uintptr) temp_fp, val);
+ delay;
+ mov_w_rm(S2, (uintptr) temp_fp + 8);
+ writeword_clobber(ad, S2, S3);
+ add_l_ri(ad, 4);
+ mov_l_rm(S2, (uintptr) temp_fp + 4);
+ writelong_clobber(ad, S2, S3);
+ add_l_ri(ad, 4);
+ mov_l_rm(S2, (uintptr) temp_fp);
+ writelong_clobber(ad, S2, S3);
+ break;
+ case 3: /* packed decimal static */
+ return -1; /* Packed */
+ case 4: /* word */
+ fmovi_mr((uintptr) temp_fp, val);
+ delay;
+ mov_l_rm(S2, (uintptr) temp_fp);
+ writeword_clobber(ad, S2, S3);
+ break;
+ case 5: /* double precision */
+ fmov_mr((uintptr) temp_fp, val);
+ delay;
+ mov_l_rm(S2, (uintptr) temp_fp + 4);
+ writelong_clobber(ad, S2, S3);
+ add_l_ri(ad, 4);
+ mov_l_rm(S2, (uintptr) temp_fp);
+ writelong_clobber(ad, S2, S3);
+ break;
+ case 6: /* byte */
+ fmovi_mr((uintptr) temp_fp, val);
+ delay;
+ mov_l_rm(S2, (uintptr) temp_fp);
+ writebyte(ad, S2, S3);
+ break;
+ default:
return -1;
}
- return -1;
+ return 0;
}
+
/* return -1 for failure, or register number for success */
-STATIC_INLINE int comp_fp_adr (uae_u32 opcode)
+STATIC_INLINE int get_fp_ad(uae_u32 opcode)
{
+ int mode;
+ int reg;
uae_s32 off;
- int mode = (opcode >> 3) & 7;
- int reg = opcode & 7;
-
- switch (mode) {
- case 2:
- case 3:
- case 4:
- mov_l_rr (S1, 8 + reg);
+
+ mode = (opcode >> 3) & 7;
+ reg = opcode & 7;
+ switch (mode)
+ {
+ case 0: /* Dn */
+ case 1: /* An */
+ return -1;
+ case 2: /* (An) */
+ case 3: /* (An)+ */
+ case 4: /* -(An) */
+ mov_l_rr(S1, 8 + reg);
return S1;
- case 5:
- off = (uae_s32) (uae_s16) comp_get_iword ((m68k_pc_offset += 2) - 2);
- mov_l_rr (S1, 8 + reg);
- add_l_ri (S1, off);
+ case 5: /* d16(An) */
+ off = (uae_s32) (uae_s16) comp_get_iword((m68k_pc_offset += 2) - 2);
+ mov_l_rr(S1, 8 + reg);
+ add_l_ri(S1, off);
return S1;
- case 7:
- switch (reg) {
- case 0:
- off = (uae_s32) (uae_s16) comp_get_iword ((m68k_pc_offset += 2) - 2);
- mov_l_ri (S1, off);
+ case 6: /* d8(An,Xn) */
+ return -1;
+ break;
+ case 7:
+ switch (reg)
+ {
+ case 0: /* abs.w */
+ off = (uae_s32) (uae_s16) comp_get_iword((m68k_pc_offset += 2) - 2);
+ mov_l_ri(S1, off);
return S1;
- case 1:
- off = comp_get_ilong ((m68k_pc_offset += 4) - 4);
- mov_l_ri (S1, off);
+ case 1: /* abs.l */
+ off = comp_get_ilong((m68k_pc_offset += 4) - 4);
+ mov_l_ri(S1, off);
return S1;
- }
+ case 2: /* d16(pc) */
+ off = start_pc + ((char *) comp_pc_p - (char *) start_pc_p) + m68k_pc_offset;
+ off += (uae_s32) (uae_s16) comp_get_iword((m68k_pc_offset += 2) - 2);
+ mov_l_ri(S1, off);
+ return S1;
+ case 3: /* d8(pc,Xn) */
+ return -1;
default:
- return -1;
+ return -1;
+ }
}
+ abort();
}
-void comp_fdbcc_opp (uae_u32 opcode, uae_u16 extra)
+
+/* return -1 for failure, or register number for success */
+void comp_fdbcc_opp (uae_u32 /* opcode */, uae_u16 /* extra */)
{
- FAIL (1);
- return;
+ if (jit_disable.fdbcc)
+ {
+ FAIL(1);
+ return;
+ }
+ FAIL(1);
+ return;
}
-void comp_fscc_opp (uae_u32 opcode, uae_u16 extra)
+
+void comp_fscc_opp(uae_u32 opcode, uae_u16 extra)
{
int reg;
- if (!currprefs.compfpu) {
- FAIL (1);
+ if (jit_disable.fscc)
+ {
+ FAIL(1);
return;
}
-#if DEBUG_FPP
- write_log (_T("JIT: fscc_opp at %08lx\n"), M68K_GETPC);
-#endif
-
- if (extra & 0x20) { /* only cc from 00 to 1f are defined */
- FAIL (1);
+ if (extra & 0x20)
+ { /* only cc from 00 to 1f are defined */
+ FAIL(1);
return;
}
- if ((opcode & 0x38) != 0) { /* We can only do to integer register */
- FAIL (1);
+ if ((opcode & 0x38) != 0)
+ { /* We can only do to integer register */
+ FAIL(1);
return;
}
- fflags_into_flags (S2);
+ fflags_into_flags(S2);
reg = (opcode & 7);
- mov_l_ri (S1, 255);
- mov_l_ri (S4, 0);
- switch (extra & 0x0f) { /* according to fpp.c, the 0x10 bit is ignored */
- case 0: break; /* set never */
- case 1: mov_l_rr (S2, S4);
- cmov_l_rr (S4, S1, 4);
- cmov_l_rr (S4, S2, 10); break;
- case 2: cmov_l_rr (S4, S1, 7); break;
- case 3: cmov_l_rr (S4, S1, 3); break;
- case 4: mov_l_rr (S2, S4);
- cmov_l_rr (S4, S1, 2);
- cmov_l_rr (S4, S2, 10); break;
- case 5: mov_l_rr (S2, S4);
- cmov_l_rr (S4, S1, 6);
- cmov_l_rr (S4, S2, 10); break;
- case 6: cmov_l_rr (S4, S1, 5); break;
- case 7: cmov_l_rr (S4, S1, 11); break;
- case 8: cmov_l_rr (S4, S1, 10); break;
- case 9: cmov_l_rr (S4, S1, 4); break;
- case 10: cmov_l_rr (S4, S1, 10); cmov_l_rr (S4, S1, 7); break;
- case 11: cmov_l_rr (S4, S1, 4); cmov_l_rr (S4, S1, 3); break;
- case 12: cmov_l_rr (S4, S1, 2); break;
- case 13: cmov_l_rr (S4, S1, 6); break;
- case 14: cmov_l_rr (S4, S1, 5); cmov_l_rr (S4, S1, 10); break;
- case 15: mov_l_rr (S4, S1); break;
+ mov_l_ri(S1, 255);
+ mov_l_ri(S4, 0);
+ switch (extra & 0x0f)
+ { /* according to fpp.c, the 0x10 bit is ignored
+ */
+ case 0:
+ break; /* set never */
+ case 1:
+ mov_l_rr(S2, S4);
+ cmov_l_rr(S4, S1, 4);
+ cmov_l_rr(S4, S2, 10);
+ break;
+ case 2:
+ cmov_l_rr(S4, S1, 7);
+ break;
+ case 3:
+ cmov_l_rr(S4, S1, 3);
+ break;
+ case 4:
+ mov_l_rr(S2, S4);
+ cmov_l_rr(S4, S1, 2);
+ cmov_l_rr(S4, S2, 10);
+ break;
+ case 5:
+ mov_l_rr(S2, S4);
+ cmov_l_rr(S4, S1, 6);
+ cmov_l_rr(S4, S2, 10);
+ break;
+ case 6:
+ cmov_l_rr(S4, S1, 5);
+ break;
+ case 7:
+ cmov_l_rr(S4, S1, 11);
+ break;
+ case 8:
+ cmov_l_rr(S4, S1, 10);
+ break;
+ case 9:
+ cmov_l_rr(S4, S1, 4);
+ break;
+ case 10:
+ cmov_l_rr(S4, S1, 10);
+ cmov_l_rr(S4, S1, 7);
+ break;
+ case 11:
+ cmov_l_rr(S4, S1, 4);
+ cmov_l_rr(S4, S1, 3);
+ break;
+ case 12:
+ cmov_l_rr(S4, S1, 2);
+ break;
+ case 13:
+ cmov_l_rr(S4, S1, 6);
+ break;
+ case 14:
+ cmov_l_rr(S4, S1, 5);
+ cmov_l_rr(S4, S1, 10);
+ break;
+ case 15:
+ mov_l_rr(S4, S1);
+ break;
}
- if (!(opcode & 0x38))
- mov_b_rr (reg, S4);
-#if 0
- else {
+ if ((opcode & 0x38) == 0)
+ {
+ mov_b_rr(reg, S4);
+ } else
+ {
abort();
- if (!comp_fp_adr (opcode)) {
- m68k_setpc (m68k_getpc () - 4);
- op_illg (opcode);
+#if 0
+ int cc;
+
+ if (get_fp_ad(opcode) < 0)
+ {
+ FAIL(1);
+ } else
+ {
+ put_byte(ad, cc ? 0xff : 0x00);
}
- else
- put_byte (ad, cc ? 0xff : 0x00);
- }
#endif
+ }
}
-void comp_ftrapcc_opp (uae_u32 opcode, uaecptr oldpc)
+
+void comp_ftrapcc_opp (uae_u32 /* opcode */, uaecptr /* oldpc */)
{
- FAIL (1);
+ FAIL(1);
return;
}
-extern unsigned long foink3, oink;
-void comp_fbcc_opp (uae_u32 opcode)
+void comp_fbcc_opp(uae_u32 opcode)
{
uae_u32 start_68k_offset = m68k_pc_offset;
- uae_u32 off, v1, v2;
+ uae_u32 off;
+ uae_u32 v1;
+ uae_u32 v2;
int cc;
- if (!currprefs.compfpu) {
- FAIL (1);
- return;
- }
-
// comp_pc_p is expected to be bound to 32-bit addresses
assert((uintptr) comp_pc_p <= 0xffffffffUL);
- if (opcode & 0x20) { /* only cc from 00 to 1f are defined */
- FAIL (1);
+ if (jit_disable.fbcc)
+ {
+ FAIL(1);
return;
}
- if (!(opcode & 0x40)) {
- off = (uae_s32) (uae_s16) comp_get_iword ((m68k_pc_offset += 2) - 2);
+ if (opcode & 0x20)
+ { /* only cc from 00 to 1f are defined */
+ FAIL(1);
+ return;
}
- else {
- off = comp_get_ilong ((m68k_pc_offset += 4) - 4);
+ if ((opcode & 0x40) == 0)
+ {
+ off = (uae_s32) (uae_s16) comp_get_iword((m68k_pc_offset += 2) - 2);
+ } else
+ {
+ off = comp_get_ilong((m68k_pc_offset += 4) - 4);
}
-
- /* Note, "off" will sometimes be (unsigned) "negative", so the following
- * uintptr can be > 0xffffffff, but the result will be correct due to
- * wraparound when truncated to 32 bit in the call to mov_l_ri. */
- mov_l_ri(S1, (uintptr)
- (comp_pc_p + off - (m68k_pc_offset - start_68k_offset)));
+ mov_l_ri(S1, (uintptr) (comp_pc_p + off - (m68k_pc_offset - start_68k_offset)));
mov_l_ri(PC_P, (uintptr) comp_pc_p);
/* Now they are both constant. Might as well fold in m68k_pc_offset */
- add_l_ri (S1, m68k_pc_offset);
- add_l_ri (PC_P, m68k_pc_offset);
+ add_l_ri(S1, m68k_pc_offset);
+ add_l_ri(PC_P, m68k_pc_offset);
m68k_pc_offset = 0;
/* according to fpp.c, the 0x10 bit is ignored
(it handles exception handling, which we don't
do, anyway ;-) */
cc = opcode & 0x0f;
- v1 = get_const (PC_P);
- v2 = get_const (S1);
- fflags_into_flags (S2);
-
- // mov_l_mi((uae_u32)&foink3,cc);
- switch (cc) {
- case 0: break; /* jump never */
- case 1:
- mov_l_rr (S2, PC_P);
- cmov_l_rr (PC_P, S1, 4);
- cmov_l_rr (PC_P, S2, 10); break;
- case 2: register_branch (v1, v2, 7); break;
- case 3: register_branch (v1, v2, 3); break;
- case 4:
- mov_l_rr (S2, PC_P);
- cmov_l_rr (PC_P, S1, 2);
- cmov_l_rr (PC_P, S2, 10); break;
- case 5:
- mov_l_rr (S2, PC_P);
- cmov_l_rr (PC_P, S1, 6);
- cmov_l_rr (PC_P, S2, 10); break;
- case 6: register_branch (v1, v2, 5); break;
- case 7: register_branch (v1, v2, 11); break;
- case 8: register_branch (v1, v2, 10); break;
- case 9: register_branch (v1, v2, 4); break;
- case 10:
- cmov_l_rr (PC_P, S1, 10);
- cmov_l_rr (PC_P, S1, 7); break;
- case 11:
- cmov_l_rr (PC_P, S1, 4);
- cmov_l_rr (PC_P, S1, 3); break;
- case 12: register_branch (v1, v2, 2); break;
- case 13: register_branch (v1, v2, 6); break;
- case 14:
- cmov_l_rr (PC_P, S1, 5);
- cmov_l_rr (PC_P, S1, 10); break;
- case 15: mov_l_rr (PC_P, S1); break;
+ v1 = get_const(PC_P);
+ v2 = get_const(S1);
+ fflags_into_flags(S2);
+
+ switch (cc)
+ {
+ case 0:
+ break; /* jump never */
+ case 1:
+ mov_l_rr(S2, PC_P);
+ cmov_l_rr(PC_P, S1, 4);
+ cmov_l_rr(PC_P, S2, 10);
+ break;
+ case 2:
+ register_branch(v1, v2, 7);
+ break;
+ case 3:
+ register_branch(v1, v2, 3);
+ break;
+ case 4:
+ mov_l_rr(S2, PC_P);
+ cmov_l_rr(PC_P, S1, 2);
+ cmov_l_rr(PC_P, S2, 10);
+ break;
+ case 5:
+ mov_l_rr(S2, PC_P);
+ cmov_l_rr(PC_P, S1, 6);
+ cmov_l_rr(PC_P, S2, 10);
+ break;
+ case 6:
+ register_branch(v1, v2, 5);
+ break;
+ case 7:
+ register_branch(v1, v2, 11);
+ break;
+ case 8:
+ register_branch(v1, v2, 10);
+ break;
+ case 9:
+ register_branch(v1, v2, 4);
+ break;
+ case 10:
+ cmov_l_rr(PC_P, S1, 10);
+ cmov_l_rr(PC_P, S1, 7);
+ break;
+ case 11:
+ cmov_l_rr(PC_P, S1, 4);
+ cmov_l_rr(PC_P, S1, 3);
+ break;
+ case 12:
+ register_branch(v1, v2, 2);
+ break;
+ case 13:
+ register_branch(v1, v2, 6);
+ break;
+ case 14:
+ cmov_l_rr(PC_P, S1, 5);
+ cmov_l_rr(PC_P, S1, 10);
+ break;
+ case 15:
+ mov_l_rr(PC_P, S1);
+ break;
}
}
-/* Floating point conditions
- The "NotANumber" part could be problematic; However, when NaN is
- encountered, the ftst instruction sets bot N and Z to 1 on the x87,
- so quite often things just fall into place. This is probably not
- accurate wrt the 68k FPU, but it is *as* accurate as this was before.
- However, some more thought should go into fixing this stuff up so
- it accurately emulates the 68k FPU.
- >=<U
- 0000 0x00: 0 --- Never jump
- 0101 0x01: Z --- jump if zero (x86: 4)
- 1000 0x02: !(NotANumber || Z || N) --- Neither Z nor N set (x86: 7)
- 1101 0x03: Z || !(NotANumber || N); --- Z or !N (x86: 4 and 3)
- 0010 0x04: N && !(NotANumber || Z); --- N and !Z (x86: hard!)
- 0111 0x05: Z || (N && !NotANumber); --- Z or N (x86: 6)
- 1010 0x06: !(NotANumber || Z); --- not Z (x86: 5)
- 1110 0x07: !NotANumber; --- not NaN (x86: 11, not parity)
- 0001 0x08: NotANumber; --- NaN (x86: 10)
- 0101 0x09: NotANumber || Z; --- Z (x86: 4)
- 1001 0x0a: NotANumber || !(N || Z); --- NaN or neither N nor Z (x86: 10 and 7)
- 1101 0x0b: NotANumber || Z || !N; --- Z or !N (x86: 4 and 3)
- 0011 0x0c: NotANumber || (N && !Z); --- N (x86: 2)
- 0111 0x0d: NotANumber || Z || N; --- Z or N (x86: 6)
- 1010 0x0e: !Z; --- not Z (x86: 5)
- 1111 0x0f: 1; --- always
-
- This is not how the 68k handles things, though --- it sets Z to 0 and N
- to the NaN's sign.... ('o' and 'i' denote differences from the above
- table)
-
- >=<U
- 0000 0x00: 0 --- Never jump
- 010o 0x01: Z --- jump if zero (x86: 4, not 10)
- 1000 0x02: !(NotANumber || Z || N) --- Neither Z nor N set (x86: 7)
- 110o 0x03: Z || !(NotANumber || N); --- Z or !N (x86: 3)
- 0010 0x04: N && !(NotANumber || Z); --- N and !Z (x86: 2, not 10)
- 011o 0x05: Z || (N && !NotANumber); --- Z or N (x86: 6, not 10)
- 1010 0x06: !(NotANumber || Z); --- not Z (x86: 5)
- 1110 0x07: !NotANumber; --- not NaN (x86: 11, not parity)
- 0001 0x08: NotANumber; --- NaN (x86: 10)
- 0101 0x09: NotANumber || Z; --- Z (x86: 4)
- 1001 0x0a: NotANumber || !(N || Z); --- NaN or neither N nor Z (x86: 10 and 7)
- 1101 0x0b: NotANumber || Z || !N; --- Z or !N (x86: 4 and 3)
- 0011 0x0c: NotANumber || (N && !Z); --- N (x86: 2)
- 0111 0x0d: NotANumber || Z || N; --- Z or N (x86: 6)
- 101i 0x0e: !Z; --- not Z (x86: 5 and 10)
- 1111 0x0f: 1; --- always
-
- Of course, this *still* doesn't mean that the x86 and 68k conditions are
- equivalent --- the handling of infinities is different, for one thing.
- On the 68k, +infinity minus +infinity is NotANumber (as it should be). On
- the x86, it is +infinity, and some exception is raised (which I suspect
- is promptly ignored) STUPID!
- The more I learn about their CPUs, the more I detest Intel....
-
- You can see this in action if you have "Benoit" (see Aminet) and
- set the exponent to 16. Wait for a long time, and marvel at the extra black
- areas outside the center one. That's where Benoit expects NaN, and the x86
- gives +infinity. [Ooops --- that must have been some kind of bug in my code.
- it no longer happens, and the resulting graphic looks much better, too]
-
- x86 conditions
- 0011 : 2
- 1100 : 3
- 0101 : 4
- 1010 : 5
- 0111 : 6
- 1000 : 7
- 0001 : 10
- 1110 : 11
- */
-void comp_fsave_opp (uae_u32 opcode)
-{
- FAIL (1);
- return;
-}
-void comp_frestore_opp (uae_u32 opcode)
+ /* Floating point conditions
+ The "NotANumber" part could be problematic; Howver, when NaN is
+ encountered, the ftst instruction sets bot N and Z to 1 on the x87,
+ so quite often things just fall into place. This is probably not
+ accurate wrt the 68k FPU, but it is *as* accurate as this was before.
+ However, some more thought should go into fixing this stuff up so
+ it accurately emulates the 68k FPU.
+>=<U
+0000 0x00: 0 --- Never jump
+0101 0x01: Z --- jump if zero (x86: 4)
+1000 0x02: !(NotANumber || Z || N) --- Neither Z nor N set (x86: 7)
+1101 0x03: Z || !(NotANumber || N); --- Z or !N (x86: 4 and 3)
+0010 0x04: N && !(NotANumber || Z); --- N and !Z (x86: hard!)
+0111 0x05: Z || (N && !NotANumber); --- Z or N (x86: 6)
+1010 0x06: !(NotANumber || Z); --- not Z (x86: 5)
+1110 0x07: !NotANumber; --- not NaN (x86: 11, not parity)
+0001 0x08: NotANumber; --- NaN (x86: 10)
+0101 0x09: NotANumber || Z; --- Z (x86: 4)
+1001 0x0a: NotANumber || !(N || Z); --- NaN or neither N nor Z (x86: 10 and 7)
+1101 0x0b: NotANumber || Z || !N; --- Z or !N (x86: 4 and 3)
+0011 0x0c: NotANumber || (N && !Z); --- N (x86: 2)
+0111 0x0d: NotANumber || Z || N; --- Z or N (x86: 6)
+1010 0x0e: !Z; --- not Z (x86: 5)
+1111 0x0f: 1; --- always
+
+This is not how the 68k handles things, though --- it sets Z to 0 and N
+to the NaN's sign.... ('o' and 'i' denote differences from the above
+table)
+
+>=<U
+0000 0x00: 0 --- Never jump
+010o 0x01: Z --- jump if zero (x86: 4, not 10)
+1000 0x02: !(NotANumber || Z || N) --- Neither Z nor N set (x86: 7)
+110o 0x03: Z || !(NotANumber || N); --- Z or !N (x86: 3)
+0010 0x04: N && !(NotANumber || Z); --- N and !Z (x86: 2, not 10)
+011o 0x05: Z || (N && !NotANumber); --- Z or N (x86: 6, not 10)
+1010 0x06: !(NotANumber || Z); --- not Z (x86: 5)
+1110 0x07: !NotANumber; --- not NaN (x86: 11, not parity)
+0001 0x08: NotANumber; --- NaN (x86: 10)
+0101 0x09: NotANumber || Z; --- Z (x86: 4)
+1001 0x0a: NotANumber || !(N || Z); --- NaN or neither N nor Z (x86: 10 and 7)
+1101 0x0b: NotANumber || Z || !N; --- Z or !N (x86: 4 and 3)
+0011 0x0c: NotANumber || (N && !Z); --- N (x86: 2)
+0111 0x0d: NotANumber || Z || N; --- Z or N (x86: 6)
+101i 0x0e: !Z; --- not Z (x86: 5 and 10)
+1111 0x0f: 1; --- always
+
+Of course, this *still* doesn't mean that the x86 and 68k conditions are
+equivalent --- the handling of infinities is different, for one thing.
+On the 68k, +infinity minus +infinity is NotANumber (as it should be). On
+the x86, it is +infinity, and some exception is raised (which I suspect
+is promptly ignored) STUPID!
+The more I learn about their CPUs, the more I detest Intel....
+
+You can see this in action if you have "Benoit" (see Aminet) and
+set the exponent to 16. Wait for a long time, and marvel at the extra black
+areas outside the center one. That's where Benoit expects NaN, and the x86
+gives +infinity. [Ooops --- that must have been some kind of bug in my code.
+it no longer happens, and the resulting graphic looks much better, too]
+
+x86 conditions
+0011 : 2
+1100 : 3
+0101 : 4
+1010 : 5
+0111 : 6
+1000 : 7
+0001 : 10
+1110 : 11
+ */
+
+#ifndef UAE
+void comp_fsave_opp(uae_u32 opcode)
{
- FAIL (1);
+ int incr = (opcode & 0x38) == 0x20 ? -1 : 1;
+ int i;
+ int ad;
+
+ if (jit_disable.fsave)
+ {
+ FAIL(1);
+ return;
+ }
+ FAIL(1);
return;
+
+ if ((ad = get_fp_ad(opcode)) < 0)
+ {
+ FAIL(1);
+ return;
+ }
+
+ if (currprefs.fpu_model == 68040)
+ {
+ /* 4 byte 68040 IDLE frame. */
+ if (incr < 0)
+ {
+ ad -= 4;
+ put_long(ad, 0x41000000);
+ } else
+ {
+ put_long(ad, 0x41000000);
+ ad += 4;
+ }
+ } else
+ {
+ if (incr < 0)
+ {
+ ad -= 4;
+ put_long(ad, 0x70000000);
+ for (i = 0; i < 5; i++)
+ {
+ ad -= 4;
+ put_long(ad, 0x00000000);
+ }
+ ad -= 4;
+ put_long(ad, 0x1f180000);
+ } else
+ {
+ put_long(ad, 0x1f180000);
+ ad += 4;
+ for (i = 0; i < 5; i++)
+ {
+ put_long(ad, 0x00000000);
+ ad += 4;
+ }
+ put_long(ad, 0x70000000);
+ ad += 4;
+ }
+ }
+ if ((opcode & 0x38) == 0x18)
+ m68k_areg(regs, opcode & 7) = ad;
+ if ((opcode & 0x38) == 0x20)
+ m68k_areg(regs, opcode & 7) = ad;
}
-extern uae_u32 xhex_pi[], xhex_exp_1[], xhex_l2_e[], xhex_ln_2[], xhex_ln_10[];
-extern uae_u32 xhex_l10_2[], xhex_l10_e[], xhex_1e16[], xhex_1e32[], xhex_1e64[];
-extern uae_u32 xhex_1e128[], xhex_1e256[], xhex_1e512[], xhex_1e1024[];
-extern uae_u32 xhex_1e2048[], xhex_1e4096[];
-extern double fp_1e8;
-extern float fp_1e1, fp_1e2, fp_1e4;
-void comp_fpp_opp (uae_u32 opcode, uae_u16 extra)
+void comp_frestore_opp(uae_u32 opcode)
{
- int reg;
- int sreg, prec = 0;
- int dreg = (extra >> 7) & 7;
- int source = (extra >> 13) & 7;
- int opmode = extra & 0x7f;
+ uae_u32 d;
+ int incr = (opcode & 0x38) == 0x20 ? -1 : 1;
+ int ad;
- if (!currprefs.compfpu) {
- FAIL (1);
+ if (jit_disable.frestore)
+ {
+ FAIL(1);
return;
}
- switch (source) {
- case 3: /* FMOVE FPx, <EA> */
- if (comp_fp_put (opcode, extra) < 0)
- FAIL (1);
+ FAIL(1);
+ return;
+
+ if ((ad = get_fp_ad(opcode)) < 0)
+ {
+ FAIL(1);
return;
- case 4: /* FMOVE.L <EA>, ControlReg */
- if (!(opcode & 0x30)) { /* Dn or An */
- if (extra & 0x1000) { /* FPCR */
- mov_l_mr (uae_p32(®s.fpcr), opcode & 15);
-#if USE_X86_FPUCW
- mov_l_rr (S1, opcode & 15);
- and_l_ri (S1, 0xf0);
- fldcw_m_indexed (S1, uae_p32(x86_fpucw));
-#endif
- return;
- }
- if (extra & 0x0800) { /* FPSR */
- FAIL (1);
- return;
- // set_fpsr(m68k_dreg (regs, opcode & 15));
+ }
+ if (currprefs.fpu_model == 68040)
+ {
+ /* 68040 */
+ if (incr < 0)
+ {
+ /* @@@ This may be wrong. */
+ ad -= 4;
+ d = get_long(ad);
+ if ((d & 0xff000000) != 0)
+ { /* Not a NULL frame? */
+ if ((d & 0x00ff0000) == 0)
+ { /* IDLE */
+ } else if ((d & 0x00ff0000) == 0x00300000)
+ { /* UNIMP */
+ ad -= 44;
+ } else if ((d & 0x00ff0000) == 0x00600000)
+ { /* BUSY */
+ ad -= 92;
+ }
}
- if (extra & 0x0400) { /* FPIAR */
- mov_l_mr (uae_p32(®s.fpiar), opcode & 15); return;
+ } else
+ {
+ d = get_long(ad);
+ ad += 4;
+ if ((d & 0xff000000) != 0)
+ { /* Not a NULL frame? */
+ if ((d & 0x00ff0000) == 0)
+ { /* IDLE */
+ } else if ((d & 0x00ff0000) == 0x00300000)
+ { /* UNIMP */
+ ad += 44;
+ } else if ((d & 0x00ff0000) == 0x00600000)
+ { /* BUSY */
+ ad += 92;
+ }
}
}
- else if ((opcode & 0x3f) == 0x3c) {
- if (extra & 0x1000) { /* FPCR */
- uae_u32 val = comp_get_ilong ((m68k_pc_offset += 4) - 4);
- mov_l_mi (uae_p32(®s.fpcr), val);
-#if USE_X86_FPUCW
- mov_l_ri (S1, val & 0xf0);
- fldcw_m_indexed (S1, uae_p32(x86_fpucw));
-#endif
- return;
+ } else
+ {
+ if (incr < 0)
+ {
+ ad -= 4;
+ d = get_long(ad);
+ if ((d & 0xff000000) != 0)
+ {
+ if ((d & 0x00ff0000) == 0x00180000)
+ ad -= 6 * 4;
+ else if ((d & 0x00ff0000) == 0x00380000)
+ ad -= 14 * 4;
+ else if ((d & 0x00ff0000) == 0x00b40000)
+ ad -= 45 * 4;
}
- if (extra & 0x0800) { /* FPSR */
- FAIL (1);
- return;
- }
- if (extra & 0x0400) { /* FPIAR */
- uae_u32 val = comp_get_ilong ((m68k_pc_offset += 4) - 4);
- mov_l_mi (uae_p32(®s.fpiar), val);
- return;
+ } else
+ {
+ d = get_long(ad);
+ ad += 4;
+ if ((d & 0xff000000) != 0)
+ {
+ if ((d & 0x00ff0000) == 0x00180000)
+ ad += 6 * 4;
+ else if ((d & 0x00ff0000) == 0x00380000)
+ ad += 14 * 4;
+ else if ((d & 0x00ff0000) == 0x00b40000)
+ ad += 45 * 4;
}
}
- FAIL (1);
- return;
- case 5: /* FMOVE.L ControlReg, <EA> */
- if (!(opcode & 0x30)) { /* Dn or An */
- if (extra & 0x1000) { /* FPCR */
- mov_l_rm (opcode & 15, uae_p32(®s.fpcr)); return;
- }
- if (extra & 0x0800) { /* FPSR */
- FAIL (1);
- return;
- }
- if (extra & 0x0400) { /* FPIAR */
- mov_l_rm (opcode & 15, uae_p32(®s.fpiar)); return;
- }
+ }
+ if ((opcode & 0x38) == 0x18)
+ m68k_areg(regs, opcode & 7) = ad;
+ if ((opcode & 0x38) == 0x20)
+ m68k_areg(regs, opcode & 7) = ad;
+}
+#endif
+
+#if defined(USE_LONG_DOUBLE) || defined(USE_QUAD_DOUBLE)
+static const fpu_register const_e = LD(2.7182818284590452353); // LD(2.7182818284590452353602874713526625);
+static const fpu_register const_log10_e = LD(0.4342944819032518276511289189166051);
+static const fpu_register const_loge_10 = LD(2.3025850929940456840179914546843642);
+#else
+static const fpu_register const_e = 2.7182818284590452354;
+static const fpu_register const_log10_e = 0.43429448190325182765;
+static const fpu_register const_loge_10 = 2.30258509299404568402;
+#endif
+
+static const fpu_register power10[] = {
+ LD(1e0), LD(1e1), LD(1e2), LD(1e4), LD(1e8), LD(1e16), LD(1e32), LD(1e64), LD(1e128), LD(1e256)
+#if defined(USE_LONG_DOUBLE) || defined(USE_QUAD_DOUBLE)
+, LD(1e512), LD(1e1024), LD(1e2048), LD(1e4096)
+#endif
+};
+
+/* 128 words, indexed through the low byte of the 68k fpu control word */
+#if 1
+/* unused*/
+static uae_u16 x86_fpucw[]={
+ 0x137f, 0x137f, 0x137f, 0x137f, 0x137f, 0x137f, 0x137f, 0x137f, /* p0r0 */
+ 0x1f7f, 0x1f7f, 0x1f7f, 0x1f7f, 0x1f7f, 0x1f7f, 0x1f7f, 0x1f7f, /* p0r1 */
+ 0x177f, 0x177f, 0x177f, 0x177f, 0x177f, 0x177f, 0x177f, 0x177f, /* p0r2 */
+ 0x1b7f, 0x1b7f, 0x1b7f, 0x1b7f, 0x1b7f, 0x1b7f, 0x1b7f, 0x1b7f, /* p0r3 */
+
+ 0x107f, 0x107f, 0x107f, 0x107f, 0x107f, 0x107f, 0x107f, 0x107f, /* p1r0 */
+ 0x1c7f, 0x1c7f, 0x1c7f, 0x1c7f, 0x1c7f, 0x1c7f, 0x1c7f, 0x1c7f, /* p1r1 */
+ 0x147f, 0x147f, 0x147f, 0x147f, 0x147f, 0x147f, 0x147f, 0x147f, /* p1r2 */
+ 0x187f, 0x187f, 0x187f, 0x187f, 0x187f, 0x187f, 0x187f, 0x187f, /* p1r3 */
+
+ 0x127f, 0x127f, 0x127f, 0x127f, 0x127f, 0x127f, 0x127f, 0x127f, /* p2r0 */
+ 0x1e7f, 0x1e7f, 0x1e7f, 0x1e7f, 0x1e7f, 0x1e7f, 0x1e7f, 0x1e7f, /* p2r1 */
+ 0x167f, 0x167f, 0x167f, 0x167f, 0x167f, 0x167f, 0x167f, 0x167f, /* p2r2 */
+ 0x1a7f, 0x1a7f, 0x1a7f, 0x1a7f, 0x1a7f, 0x1a7f, 0x1a7f, 0x1a7f, /* p2r3 */
+
+ 0x137f, 0x137f, 0x137f, 0x137f, 0x137f, 0x137f, 0x137f, 0x137f, /* p3r0 */
+ 0x1f7f, 0x1f7f, 0x1f7f, 0x1f7f, 0x1f7f, 0x1f7f, 0x1f7f, 0x1f7f, /* p3r1 */
+ 0x177f, 0x177f, 0x177f, 0x177f, 0x177f, 0x177f, 0x177f, 0x177f, /* p3r2 */
+ 0x1b7f, 0x1b7f, 0x1b7f, 0x1b7f, 0x1b7f, 0x1b7f, 0x1b7f, 0x1b7f /* p3r3 */
+};
+#endif
+
+
+void comp_fpp_opp(uae_u32 opcode, uae_u16 extra)
+{
+ int reg;
+ int src;
+
+ switch ((extra >> 13) & 0x7)
+ {
+ case 1: /* illegal */
+ break;
+
+ case 3: /* FMOVE Fpn,<ea> */
+ /* 2nd most common */
+ if (jit_disable.fmove)
+ {
+ FAIL(1);
+ return;
+ }
+
+ if (put_fp_value((extra >> 7) & 7, opcode, extra) < 0)
+ {
+ FAIL(1);
+ return;
}
- FAIL (1);
return;
- case 6:
- case 7:
+
+ case 6: /* FMOVEM <ea>,<reglist> */
+ case 7: /* FMOVEM <reglist>,<ea> */
+ if (jit_disable.fmovem)
{
+ FAIL(1);
+ return;
+ }
+
+ {
+ int ad;
uae_u32 list = 0;
int incr = 0;
- if (extra & 0x2000) {
- int ad;
+ if (extra & 0x2000)
+ {
/* FMOVEM FPP->memory */
- switch ((extra >> 11) & 3) { /* Get out early if failure */
- case 0:
- case 2:
+ switch ((extra >> 11) & 3)
+ { /* Get out early if failure */
+ case 0: /* static pred */
+ case 2: /* static postinc */
break;
- case 1:
- case 3:
- default:
- FAIL (1); return;
+ case 1: /* dynamic pred */
+ case 3: /* dynamic postinc */
+ default:
+ FAIL(1);
+ return;
}
- ad = comp_fp_adr (opcode);
- if (ad < 0) {
- m68k_setpc (m68k_getpc () - 4);
- op_illg (opcode);
+ if ((ad = get_fp_ad(opcode)) < 0)
+ {
+ FAIL(1);
return;
}
- switch ((extra >> 11) & 3) {
- case 0: /* static pred */
+ switch ((extra >> 11) & 3)
+ {
+ case 0: /* static pred */
list = extra & 0xff;
incr = -1;
break;
- case 2: /* static postinc */
+ case 2: /* static postinc */
list = extra & 0xff;
incr = 1;
break;
- case 1: /* dynamic pred */
- case 3: /* dynamic postinc */
- abort ();
+ case 1: /* dynamic pred */
+ case 3: /* dynamic postinc */
+ abort();
}
- if (incr < 0) { /* Predecrement */
- for (reg = 7; reg >= 0; reg--) {
- if (list & 0x80) {
- fmov_ext_mr ((uintptr) temp_fp, reg);
- sub_l_ri (ad, 4);
- mov_l_rm (S2, (uintptr) temp_fp);
- writelong_clobber (ad, S2, S3);
- sub_l_ri (ad, 4);
- mov_l_rm (S2, (uintptr) temp_fp + 4);
- writelong_clobber (ad, S2, S3);
- sub_l_ri (ad, 4);
- mov_w_rm (S2, (uintptr) temp_fp + 8);
- writeword_clobber (ad, S2, S3);
+ if (incr < 0)
+ { /* Predecrement */
+ for (reg = 7; reg >= 0; reg--)
+ {
+ if (list & 0x80)
+ {
+ fmov_ext_mr((uintptr) temp_fp, reg);
+ delay;
+ sub_l_ri(ad, 4);
+ mov_l_rm(S2, (uintptr) temp_fp);
+ writelong_clobber(ad, S2, S3);
+ sub_l_ri(ad, 4);
+ mov_l_rm(S2, (uintptr) temp_fp + 4);
+ writelong_clobber(ad, S2, S3);
+ sub_l_ri(ad, 4);
+ mov_w_rm(S2, (uintptr) temp_fp + 8);
+ writeword_clobber(ad, S2, S3);
}
list <<= 1;
}
- } else { /* Postincrement */
- for (reg = 0; reg <= 7; reg++) {
- if (list & 0x80) {
- fmov_ext_mr ((uintptr) temp_fp, reg);
- mov_w_rm (S2, (uintptr) temp_fp + 8);
- writeword_clobber (ad, S2, S3);
- add_l_ri (ad, 4);
- mov_l_rm (S2, (uintptr) temp_fp + 4);
- writelong_clobber (ad, S2, S3);
- add_l_ri (ad, 4);
- mov_l_rm (S2, (uintptr) temp_fp);
- writelong_clobber (ad, S2, S3);
- add_l_ri (ad, 4);
+ } else
+ { /* Postincrement */
+ for (reg = 0; reg < 8; reg++)
+ {
+ if (list & 0x80)
+ {
+ fmov_ext_mr((uintptr) temp_fp, reg);
+ delay;
+ mov_w_rm(S2, (uintptr) temp_fp + 8);
+ writeword_clobber(ad, S2, S3);
+ add_l_ri(ad, 4);
+ mov_l_rm(S2, (uintptr) temp_fp + 4);
+ writelong_clobber(ad, S2, S3);
+ add_l_ri(ad, 4);
+ mov_l_rm(S2, (uintptr) temp_fp);
+ writelong_clobber(ad, S2, S3);
+ add_l_ri(ad, 4);
}
list <<= 1;
}
}
if ((opcode & 0x38) == 0x18)
- mov_l_rr ((opcode & 7) + 8, ad);
+ mov_l_rr((opcode & 7) + 8, ad);
if ((opcode & 0x38) == 0x20)
- mov_l_rr ((opcode & 7) + 8, ad);
- } else {
+ mov_l_rr((opcode & 7) + 8, ad);
+ } else
+ {
/* FMOVEM memory->FPP */
int ad;
- switch ((extra >> 11) & 3) { /* Get out early if failure */
- case 0:
- case 2:
+
+ switch ((extra >> 11) & 3)
+ { /* Get out early if failure */
+ case 0: /* static pred */
+ case 2: /* static postinc */
break;
- case 1:
- case 3:
- default:
- FAIL (1); return;
+ case 1: /* dynamic pred */
+ case 3: /* dynamic postinc */
+ default:
+ FAIL(1);
+ return;
}
- ad = comp_fp_adr (opcode);
- if (ad < 0) {
- m68k_setpc (m68k_getpc () - 4);
- op_illg (opcode);
+ ad = get_fp_ad(opcode);
+ if (ad < 0)
+ {
+ D(bug("no ad\n"));
+ FAIL(1);
return;
}
- switch ((extra >> 11) & 3) {
- case 0: /* static pred */
+ switch ((extra >> 11) & 3)
+ {
+ case 0: /* static pred */
list = extra & 0xff;
incr = -1;
break;
- case 2: /* static postinc */
+ case 2: /* static postinc */
list = extra & 0xff;
incr = 1;
break;
- case 1: /* dynamic pred */
- case 3: /* dynamic postinc */
- abort ();
+ case 1: /* dynamic pred */
+ case 3: /* dynamic postinc */
+ abort();
}
- if (incr < 0) {
+ if (incr < 0)
+ {
// not reached
- for (reg = 7; reg >= 0; reg--) {
- if (list & 0x80) {
- sub_l_ri (ad, 4);
- readlong (ad, S2, S3);
- mov_l_mr ((uintptr) (temp_fp), S2);
- sub_l_ri (ad, 4);
- readlong (ad, S2, S3);
- mov_l_mr ((uintptr) (temp_fp) +4, S2);
- sub_l_ri (ad, 4);
- readword (ad, S2, S3);
- mov_w_mr (((uintptr) temp_fp) + 8, S2);
- fmov_ext_rm (reg, (uintptr) (temp_fp));
+ for (reg = 7; reg >= 0; reg--)
+ {
+ if (list & 0x80)
+ {
+ sub_l_ri(ad, 4);
+ readlong(ad, S2, S3);
+ mov_l_mr((uintptr) (temp_fp), S2);
+ sub_l_ri(ad, 4);
+ readlong(ad, S2, S3);
+ mov_l_mr((uintptr) (temp_fp) + 4, S2);
+ sub_l_ri(ad, 4);
+ readword(ad, S2, S3);
+ mov_w_mr(((uintptr) temp_fp) + 8, S2);
+ delay2;
+ fmov_ext_rm(reg, (uintptr) (temp_fp));
}
list <<= 1;
}
- } else {
- for (reg = 0; reg <= 7; reg++) {
- if (list & 0x80) {
- readword (ad, S2, S3);
- mov_w_mr (((uintptr) temp_fp) + 8, S2);
- add_l_ri (ad, 4);
- readlong (ad, S2, S3);
- mov_l_mr ((uintptr) (temp_fp) +4, S2);
- add_l_ri (ad, 4);
- readlong (ad, S2, S3);
- mov_l_mr ((uintptr) (temp_fp), S2);
- add_l_ri (ad, 4);
- fmov_ext_rm (reg, (uintptr) (temp_fp));
+ } else
+ {
+ for (reg = 0; reg < 8; reg++)
+ {
+ if (list & 0x80)
+ {
+ readword(ad, S2, S3);
+ mov_w_mr(((uintptr) temp_fp) + 8, S2);
+ add_l_ri(ad, 4);
+ readlong(ad, S2, S3);
+ mov_l_mr((uintptr) (temp_fp) + 4, S2);
+ add_l_ri(ad, 4);
+ readlong(ad, S2, S3);
+ mov_l_mr((uintptr) (temp_fp), S2);
+ add_l_ri(ad, 4);
+ delay2;
+ fmov_ext_rm(reg, (uintptr) (temp_fp));
}
list <<= 1;
}
}
if ((opcode & 0x38) == 0x18)
- mov_l_rr ((opcode & 7) + 8, ad);
+ mov_l_rr((opcode & 7) + 8, ad);
if ((opcode & 0x38) == 0x20)
- mov_l_rr ((opcode & 7) + 8, ad);
+ mov_l_rr((opcode & 7) + 8, ad);
}
}
return;
-#if 0
- case 6: /* FMOVEM <EA>, FPx-FPz */
- if (!(extra & 0x0800)) {
- uae_u32 list = extra & 0xff;
- int ad;
- if ((ad = comp_fp_adr(opcode)) < 0) {FAIL(1);return;}
- while (list) {
- if (extra & 0x1000) { /* postincrement */
- readword(ad,S2,S3);
- mov_w_mr((uae_p32(temp_fp))+8,S2);
- add_l_ri(ad,4);
- readlong(ad,S2,S3);
- mov_l_mr((uae_u32)(temp_fp)+4,S2);
- add_l_ri(ad,4);
- readlong(ad,S2,S3);
- mov_l_mr((uae_u32)(temp_fp),S2);
- add_l_ri(ad,4);
- fmov_ext_rm(fpp_movem_index1[list],(uae_u32)(temp_fp));
- } else { /* predecrement */
- sub_l_ri(ad,4);
- readlong(ad,S2,S3);
- mov_l_mr((uae_u32)(temp_fp),S2);
- sub_l_ri(ad,4);
- readlong(ad,S2,S3);
- mov_l_mr((uae_u32)(temp_fp)+4,S2);
- sub_l_ri(ad,4);
- readword(ad,S2,S3);
- mov_w_mr((uae_p32(temp_fp))+8,S2);
- fmov_ext_rm(fpp_movem_index2[list],(uae_u32)(temp_fp));
+
+ case 4: /* FMOVEM <ea>,<control> */
+ case 5: /* FMOVEM <control>,<ea> */
+ if (jit_disable.fmovec)
+ {
+ FAIL(1);
+ return;
+ }
+
+ /* rare */
+ if ((opcode & 0x30) == 0)
+ {
+ /* <ea> = Dn or An */
+ if (extra & 0x2000)
+ {
+ if (extra & 0x1000)
+ {
+#if HANDLE_FPCR
+ mov_l_rm(opcode & 15, (uintptr) & fpu.fpcr.rounding_mode);
+ or_l_rm(opcode & 15, (uintptr) & fpu.fpcr.rounding_precision);
+#else
+ FAIL(1);
+ return;
+#endif
+ }
+ if (extra & 0x0800)
+ {
+ FAIL(1);
+ return;
+ }
+ if (extra & 0x0400)
+ {
+ /* FPIAR: fixme; we cannot correctly return the address from compiled code */
+#ifdef UAE
+ mov_l_rm(opcode & 15, (uintptr)®s.fpiar);
+#else
+ mov_l_rm(opcode & 15, (uintptr) & fpu.instruction_address);
+#endif
+ return;
}
- list = fpp_movem_next[list];
+ } else
+ {
+ // gb-- moved here so that we may FAIL() without generating any code
+ if (extra & 0x0800)
+ {
+ // set_fpsr(m68k_dreg (regs, opcode & 15));
+ FAIL(1);
+ return;
+ }
+ if (extra & 0x1000)
+ {
+#if HANDLE_FPCR
+#if defined(FPU_USE_X86_ROUNDING_MODE) && defined(FPU_USE_X86_ROUNDING_PRECISION)
+ FAIL(1);
+ return;
+#endif
+ mov_l_rr(S1, opcode & 15);
+ mov_l_rr(S2, opcode & 15);
+ and_l_ri(S1, FPCR_ROUNDING_PRECISION);
+ and_l_ri(S2, FPCR_ROUNDING_MODE);
+ mov_l_mr((uintptr) & fpu.fpcr.rounding_precision, S1);
+ mov_l_mr((uintptr) & fpu.fpcr.rounding_mode, S2);
+#else
+ FAIL(1);
+ return;
+#endif
+ }
+ if (extra & 0x0400)
+ {
+ /* FPIAR: does that make sense at all? */
+#ifdef UAE
+ mov_l_mr((uintptr)®s.fpiar, opcode & 15);
+#else
+ mov_l_mr((uintptr) & fpu.instruction_address, opcode & 15);
+#endif
+ }
+ return;
}
- if ((opcode & 0x38) == 0x18)
- mov_l_rr((opcode & 7)+8,ad);
- return;
- } /* no break for dynamic register list */
- case 7: /* FMOVEM FPx-FPz, <EA> */
- if (!(extra & 0x0800)) {
- uae_u32 list = extra & 0xff;
- int ad;
- if ((ad = comp_fp_adr(opcode)) < 0) {FAIL(1);return;}
- while (list) {
- if (extra & 0x1000) { /* postincrement */
- fmov_ext_mr(uae_p32(temp_fp),fpp_movem_index2[list]);
- mov_w_rm(S2,uae_p32(temp_fp)+8);
- writeword_clobber(ad,S2,S3);
- add_l_ri(ad,4);
- mov_l_rm(S2,uae_p32(temp_fp)+4);
- writelong_clobber(ad,S2,S3);
- add_l_ri(ad,4);
- mov_l_rm(S2,uae_p32(temp_fp));
- writelong_clobber(ad,S2,S3);
- add_l_ri(ad,4);
- } else { /* predecrement */
- fmov_ext_mr(uae_p32(temp_fp),fpp_movem_index2[list]);
- sub_l_ri(ad,4);
- mov_l_rm(S2,uae_p32(temp_fp));
- writelong_clobber(ad,S2,S3);
- sub_l_ri(ad,4);
- mov_l_rm(S2,uae_p32(temp_fp)+4);
- writelong_clobber(ad,S2,S3);
- sub_l_ri(ad,4);
- mov_w_rm(S2,uae_p32(temp_fp)+8);
- writeword_clobber(ad,S2,S3);
+ } else if ((opcode & 0x3f) == 0x3c)
+ {
+ /* <ea> = #imm */
+ if ((extra & 0x2000) == 0)
+ {
+ // gb-- moved here so that we may FAIL() without generating any code
+ if (extra & 0x0800)
+ {
+ FAIL(1);
+ return;
+ }
+ if (extra & 0x1000)
+ {
+ comp_get_ilong((m68k_pc_offset += 4) - 4);
+#if HANDLE_FPCR
+#if defined(FPU_USE_X86_ROUNDING_MODE) && defined(FPU_USE_X86_ROUNDING_PRECISION)
+ FAIL(1);
+ return;
+#endif
+ // mov_l_mi((uintptr)®s.fpcr,val);
+ mov_l_ri(S1, val);
+ mov_l_ri(S2, val);
+ and_l_ri(S1, FPCR_ROUNDING_PRECISION);
+ and_l_ri(S2, FPCR_ROUNDING_MODE);
+ mov_l_mr((uintptr) & fpu.fpcr.rounding_precision, S1);
+ mov_l_mr((uintptr) & fpu.fpcr.rounding_mode, S2);
+#else
+ FAIL(1);
+ return;
+#endif
+ }
+ if (extra & 0x0400)
+ {
+ uae_u32 val = comp_get_ilong((m68k_pc_offset += 4) - 4);
+#ifdef UAE
+ mov_l_mi((uintptr)®s.fpiar, val);
+#else
+ mov_l_mi((uintptr) & fpu.instruction_address, val);
+#endif
}
- list = fpp_movem_next[list];
+ return;
}
- if ((opcode & 0x38) == 0x20)
- mov_l_rr((opcode & 7)+8,ad);
+ FAIL(1);
+ return;
+ } else if (extra & 0x2000)
+ {
+ FAIL(1);
+ return;
+ } else
+ {
+ FAIL(1);
return;
- } /* no break */
- write_log (_T("fallback from JIT FMOVEM dynamic register list\n"));
+ }
FAIL(1);
return;
-#endif
- case 2: /* from <EA> to FPx */
- dont_care_fflags ();
- if ((extra & 0xfc00) == 0x5c00) { /* FMOVECR */
- //write_log (_T("JIT FMOVECR %x\n"), opmode);
- switch (opmode) {
- case 0x00:
- fmov_pi (dreg);
- break;
- case 0x0b:
- fmov_ext_rm (dreg, uae_p32(&xhex_l10_2));
- break;
- case 0x0c:
- fmov_ext_rm (dreg, uae_p32(&xhex_exp_1));
- break;
- case 0x0d:
- fmov_log2_e (dreg);
- break;
- case 0x0e:
- fmov_ext_rm (dreg, uae_p32(&xhex_l10_e));
- break;
- case 0x0f:
- fmov_0 (dreg);
- break;
- case 0x30:
- fmov_loge_2 (dreg);
- break;
- case 0x31:
- fmov_ext_rm (dreg, uae_p32(&xhex_ln_10));
- break;
- case 0x32:
- fmov_1 (dreg);
- break;
- case 0x33:
- fmovs_rm (dreg, uae_p32(&fp_1e1));
- break;
- case 0x34:
- fmovs_rm (dreg, uae_p32(&fp_1e2));
- break;
- case 0x35:
- fmovs_rm (dreg, uae_p32(&fp_1e4));
- break;
- case 0x36:
- fmov_rm (dreg, uae_p32(&fp_1e8));
+
+ case 0:
+ case 2: /* Extremely common */
+ reg = (extra >> 7) & 7;
+ if ((extra & 0xfc00) == 0x5c00)
+ {
+ if (jit_disable.fmovecr)
+ {
+ FAIL(1);
+ return;
+ }
+
+ switch (extra & 0x7f)
+ {
+ case 0x00:
+ fmov_pi(reg);
break;
- case 0x37:
- fmov_ext_rm (dreg, uae_p32(&xhex_1e16));
+ case 0x0b:
+ fmov_log10_2(reg);
break;
- case 0x38:
- fmov_ext_rm (dreg, uae_p32(&xhex_1e32));
+ case 0x0c:
+#if defined(USE_LONG_DOUBLE) || defined(USE_QUAD_DOUBLE)
+ fmov_ext_rm(reg, (uintptr) & const_e);
+#else
+ fmov_rm(reg, (uintptr) & const_e);
+#endif
break;
- case 0x39:
- fmov_ext_rm (dreg, uae_p32(&xhex_1e64));
+ case 0x0d:
+ fmov_log2_e(reg);
break;
- case 0x3a:
- fmov_ext_rm (dreg, uae_p32(&xhex_1e128));
+ case 0x0e:
+#if defined(USE_LONG_DOUBLE) || defined(USE_QUAD_DOUBLE)
+ fmov_ext_rm(reg, (uintptr) & const_log10_e);
+#else
+ fmov_rm(reg, (uintptr) & const_log10_e);
+#endif
break;
- case 0x3b:
- fmov_ext_rm (dreg, uae_p32(&xhex_1e256));
+ case 0x0f:
+ fmov_0(reg);
break;
- case 0x3c:
- fmov_ext_rm (dreg, uae_p32(&xhex_1e512));
+ case 0x30:
+ fmov_loge_2(reg);
break;
- case 0x3d:
- fmov_ext_rm (dreg, uae_p32(&xhex_1e1024));
+ case 0x31:
+#if defined(USE_LONG_DOUBLE) || defined(USE_QUAD_DOUBLE)
+ fmov_ext_rm(reg, (uintptr) & const_loge_10);
+#else
+ fmov_rm(reg, (uintptr) & const_loge_10);
+#endif
break;
- case 0x3e:
- fmov_ext_rm (dreg, uae_p32(&xhex_1e2048));
+ case 0x32:
+ fmov_1(reg);
break;
- case 0x3f:
- fmov_ext_rm (dreg, uae_p32(&xhex_1e4096));
+ case 0x33:
+ case 0x34:
+ case 0x35:
+ case 0x36:
+ case 0x37:
+ case 0x38:
+ case 0x39:
+ case 0x3a:
+ case 0x3b:
+#if defined(USE_LONG_DOUBLE) || defined(USE_QUAD_DOUBLE)
+ case 0x3c:
+ case 0x3d:
+ case 0x3e:
+ case 0x3f:
+ fmov_ext_rm(reg, (uintptr) (power10 + (extra & 0x7f) - 0x32));
+#else
+ fmov_rm(reg, (uintptr) (power10 + (extra & 0x7f) - 0x32));
+#endif
break;
- default:
- FAIL (1);
+ default:
+ /* This is not valid, so we fail */
+ FAIL(1);
return;
}
- fmov_rr (FP_RESULT, dreg);
return;
}
- if (opmode & 0x20) /* two operands, so we need a scratch reg */
- sreg = FS1;
- else /* one operand only, thus we can load the argument into dreg */
- sreg = dreg;
- if ((prec = comp_fp_get (opcode, extra, sreg)) < 0) {
- FAIL (1);
- return;
- }
- if (!opmode) { /* FMOVE <EA>,FPx */
- fmov_rr (FP_RESULT, dreg);
- return;
- }
- /* no break here for <EA> to dreg */
- case 0: /* directly from sreg to dreg */
- if (!source) { /* no <EA> */
- dont_care_fflags ();
- sreg = (extra >> 10) & 7;
- }
- switch (opmode) {
- case 0x00: /* FMOVE */
- fmov_rr (dreg, sreg);
+
+ switch (extra & 0x7f)
+ {
+ case 0x00: /* FMOVE */
+ case 0x40: /* FSMOVE: Explicit rounding. This is just a quick fix. Same
+ * for all other cases that have three choices */
+ case 0x44: /* FDMOVE */
+ if (jit_disable.fmove)
+ {
+ FAIL(1);
+ return;
+ }
+
+ dont_care_fflags();
+ src = get_fp_value(opcode, extra);
+ if (src < 0)
+ {
+ FAIL(1); /* Illegal instruction */
+ return;
+ }
+ fmov_rr(reg, src);
+ MAKE_FPSR(src);
break;
- case 0x01: /* FINT */
- frndint_rr (dreg, sreg);
+ case 0x01: /* FINT */
+ if (jit_disable.fint)
+ {
+ FAIL(1);
+ return;
+ }
+
+ FAIL(1);
+ return;
+ dont_care_fflags();
break;
- case 0x02: /* FSINH */
- fsinh_rr (dreg, sreg);
+ case 0x02: /* FSINH */
+ if (jit_disable.fsinh)
+ {
+ FAIL(1);
+ return;
+ }
+
+ FAIL(1);
+ return;
+ dont_care_fflags();
break;
- case 0x03: /* FINTRZ */
-#if USE_X86_FPUCW /* if we have control over the CW, we can do this */
- if (0 && (regs.fpcr & 0xf0) == 0x10) /* maybe unsafe, because this test is done */
- frndint_rr (dreg, sreg); /* during the JIT compilation and not at runtime */
- else {
- mov_l_ri (S1, 0x10); /* extended round to zero */
- fldcw_m_indexed (S1, uae_p32(x86_fpucw));
- frndint_rr (dreg, sreg);
- mov_l_rm (S1, uae_p32(®s.fpcr));
- and_l_ri (S1, 0xf0); /* restore control word */
- fldcw_m_indexed (S1, uae_p32(x86_fpucw));
+ case 0x03: /* FINTRZ */
+ if (jit_disable.fintrz)
+ {
+ FAIL(1);
+ return;
}
+#ifdef USE_X86_FPUCW
+ /* If we have control over the CW, we can do this */
+ dont_care_fflags();
+ src = get_fp_value(opcode, extra);
+ if (src < 0)
+ {
+ FAIL(1); /* Illegal instruction */
+ return;
+ }
+ mov_l_ri(S1, 16); /* Switch to "round to zero" mode */
+ fldcw_m_indexed(S1, (uintptr) x86_fpucw);
+
+ frndint_rr(reg, src);
+
+ /* restore control word */
+ mov_l_rm(S1, (uintptr) & regs.fpcr);
+ and_l_ri(S1, 0x000000f0);
+ fldcw_m_indexed(S1, (uintptr) x86_fpucw);
+
+ MAKE_FPSR(reg);
break;
#endif
- FAIL (1);
+ FAIL(1);
return;
- case 0x04: /* FSQRT */
- fsqrt_rr (dreg, sreg);
- break;
- case 0x06: /* FLOGNP1 */
- flogNP1_rr (dreg, sreg);
- break;
- case 0x08: /* FETOXM1 */
- fetoxM1_rr (dreg, sreg);
- break;
- case 0x09: /* FTANH */
- ftanh_rr (dreg, sreg);
- break;
- case 0x0a: /* FATAN */
- fatan_rr (dreg, sreg);
- break;
- case 0x0c: /* FASIN */
- fasin_rr (dreg, sreg);
break;
- case 0x0d: /* FATANH */
- fatanh_rr (dreg, sreg);
- break;
- case 0x0e: /* FSIN */
- fsin_rr (dreg, sreg);
- break;
- case 0x0f: /* FTAN */
- ftan_rr (dreg, sreg);
- break;
- case 0x10: /* FETOX */
- fetox_rr (dreg, sreg);
- break;
- case 0x11: /* FTWOTOX */
- ftwotox_rr (dreg, sreg);
- break;
- case 0x12: /* FTENTOX */
- ftentox_rr (dreg, sreg);
- break;
- case 0x14: /* FLOGN */
- flogN_rr (dreg, sreg);
+ case 0x04: /* FSQRT */
+ case 0x41: /* FSSQRT */
+ case 0x45: /* FDSQRT */
+ if (jit_disable.fsqrt)
+ {
+ FAIL(1);
+ return;
+ }
+
+ dont_care_fflags();
+ src = get_fp_value(opcode, extra);
+ if (src < 0)
+ {
+ FAIL(1); /* Illegal instruction */
+ return;
+ }
+ fsqrt_rr(reg, src);
+ MAKE_FPSR(reg);
break;
- case 0x15: /* FLOG10 */
- flog10_rr (dreg, sreg);
+ case 0x06: /* FLOGNP1 */
+ if (jit_disable.flognp1)
+ {
+ FAIL(1);
+ return;
+ }
+
+ FAIL(1);
+ return;
+ dont_care_fflags();
break;
- case 0x16: /* FLOG2 */
- flog2_rr (dreg, sreg);
+ case 0x08: /* FETOXM1 */
+ if (jit_disable.fetoxm1)
+ {
+ FAIL(1);
+ return;
+ }
+
+ FAIL(1);
+ return;
+ dont_care_fflags();
break;
- case 0x18: /* FABS */
- fabs_rr (dreg, sreg);
+ case 0x09: /* FTANH */
+ if (jit_disable.ftanh)
+ {
+ FAIL(1);
+ return;
+ }
+
+ FAIL(1);
+ return;
+ dont_care_fflags();
break;
- case 0x19: /* FCOSH */
- fcosh_rr (dreg, sreg);
+ case 0x0a: /* FATAN */
+ if (jit_disable.fatan)
+ {
+ FAIL(1);
+ return;
+ }
+
+ FAIL(1);
+ return;
+ dont_care_fflags();
break;
- case 0x1a: /* FNEG */
- fneg_rr (dreg, sreg);
+ case 0x0c: /* FASIN */
+ if (jit_disable.fasin)
+ {
+ FAIL(1);
+ return;
+ }
+
+ FAIL(1);
+ return;
+ dont_care_fflags();
break;
- case 0x1c: /* FACOS */
-#if USE_X86_FPUCW
- mov_l_ri (S1, (regs.fpcr & 0xC0) | 0x00);
- fldcw_m_indexed (S1, uae_p32(x86_fpucw));
- facos_rr (dreg, sreg);
- mov_l_rm (S1, uae_p32(®s.fpcr));
- and_l_ri (S1, 0xf0); /* restore control word */
- fldcw_m_indexed (S1, uae_p32(x86_fpucw));
-#else
- facos_rr (dreg, sreg);
-#endif
+ case 0x0d: /* FATANH */
+ if (jit_disable.fatanh)
+ {
+ FAIL(1);
+ return;
+ }
+
+ FAIL(1);
+ return;
+ dont_care_fflags();
break;
- case 0x1d: /* FCOS */
- fcos_rr (dreg, sreg);
+ case 0x0e: /* FSIN */
+ if (jit_disable.fsin)
+ {
+ FAIL(1);
+ return;
+ }
+
+ dont_care_fflags();
+ src = get_fp_value(opcode, extra);
+ if (src < 0)
+ {
+ FAIL(1); /* Illegal instruction */
+ return;
+ }
+ fsin_rr(reg, src);
+ MAKE_FPSR(reg);
break;
- case 0x1e: /* FGETEXP */
- fgetexp_rr (dreg, sreg);
+ case 0x0f: /* FTAN */
+ if (jit_disable.ftan)
+ {
+ FAIL(1);
+ return;
+ }
+
+ FAIL(1);
+ return;
+ dont_care_fflags();
break;
- case 0x1f: /* FGETMAN */
- fgetman_rr (dreg, sreg);
+ case 0x10: /* FETOX */
+ if (jit_disable.fetox)
+ {
+ FAIL(1);
+ return;
+ }
+
+ dont_care_fflags();
+ src = get_fp_value(opcode, extra);
+ if (src < 0)
+ {
+ FAIL(1); /* Illegal instruction */
+ return;
+ }
+ fetox_rr(reg, src);
+ MAKE_FPSR(reg);
break;
- case 0x20: /* FDIV */
- fdiv_rr (dreg, sreg);
+ case 0x11: /* FTWOTOX */
+ if (jit_disable.ftwotox)
+ {
+ FAIL(1);
+ return;
+ }
+
+ dont_care_fflags();
+ src = get_fp_value(opcode, extra);
+ if (src < 0)
+ {
+ FAIL(1); /* Illegal instruction */
+ return;
+ }
+ ftwotox_rr(reg, src);
+ MAKE_FPSR(reg);
break;
- case 0x21: /* FMOD */
- frem_rr (dreg, sreg);
+ case 0x12: /* FTENTOX */
+ if (jit_disable.ftentox)
+ {
+ FAIL(1);
+ return;
+ }
+
+ FAIL(1);
+ return;
+ dont_care_fflags();
break;
- case 0x22: /* FADD */
- fadd_rr (dreg, sreg);
+ case 0x14: /* FLOGN */
+ if (jit_disable.flogn)
+ {
+ FAIL(1);
+ return;
+ }
+
+ FAIL(1);
+ return;
+ dont_care_fflags();
break;
- case 0x23: /* FMUL */
- fmul_rr (dreg, sreg);
+ case 0x15: /* FLOG10 */
+ if (jit_disable.flog10)
+ {
+ FAIL(1);
+ return;
+ }
+
+ FAIL(1);
+ return;
+ dont_care_fflags();
break;
- case 0x24: /* FSGLDIV is not exactly the same as FSDIV, */
- /* because both operands should be SINGLE precision, too */
- case 0x60: /* FSDIV */
- fdiv_rr (dreg, sreg);
- if (!currprefs.fpu_strict) /* faster, but less strict rounding */
- break;
-#if USE_X86_FPUCW
- if ((regs.fpcr & 0xC0) == 0x40) /* if SINGLE precision */
- break;
-#endif
- fcuts_r (dreg);
+ case 0x16: /* FLOG2 */
+ if (jit_disable.flog2)
+ {
+ FAIL(1);
+ return;
+ }
+
+ dont_care_fflags();
+ src = get_fp_value(opcode, extra);
+ if (src < 0)
+ {
+ FAIL(1); /* Illegal instruction */
+ return;
+ }
+ flog2_rr(reg, src);
+ MAKE_FPSR(reg);
break;
- case 0x25: /* FREM */
- frem1_rr (dreg, sreg);
+ case 0x18: /* FABS */
+ case 0x58: /* FSABS */
+ case 0x5c: /* FDABS */
+ if (jit_disable.fabs)
+ {
+ FAIL(1);
+ return;
+ }
+
+ dont_care_fflags();
+ src = get_fp_value(opcode, extra);
+ if (src < 0)
+ {
+ FAIL(1); /* Illegal instruction */
+ return;
+ }
+ fabs_rr(reg, src);
+ MAKE_FPSR(reg);
break;
- case 0x26: /* FSCALE */
- fscale_rr (dreg, sreg);
+ case 0x19: /* FCOSH */
+ if (jit_disable.fcosh)
+ {
+ FAIL(1);
+ return;
+ }
+
+ FAIL(1);
+ return;
+ dont_care_fflags();
break;
- case 0x27: /* FSGLMUL is not exactly the same as FSMUL, */
- /* because both operands should be SINGLE precision, too */
- case 0x63: /* FSMUL */
- fmul_rr (dreg, sreg);
- if (!currprefs.fpu_strict) /* faster, but less strict rounding */
- break;
-#if USE_X86_FPUCW
- if ((regs.fpcr & 0xC0) == 0x40) /* if SINGLE precision */
- break;
-#endif
- fcuts_r (dreg);
+ case 0x1a: /* FNEG */
+ case 0x5a: /* FSNEG */
+ case 0x5e: /* FDNEG */
+ if (jit_disable.fneg)
+ {
+ FAIL(1);
+ return;
+ }
+
+ dont_care_fflags();
+ src = get_fp_value(opcode, extra);
+ if (src < 0)
+ {
+ FAIL(1); /* Illegal instruction */
+ return;
+ }
+ fneg_rr(reg, src);
+ MAKE_FPSR(reg);
break;
- case 0x28: /* FSUB */
- fsub_rr (dreg, sreg);
+ case 0x1c: /* FACOS */
+ if (jit_disable.facos)
+ {
+ FAIL(1);
+ return;
+ }
+
+ FAIL(1);
+ return;
+ dont_care_fflags();
break;
- case 0x30: /* FSINCOS */
- case 0x31:
- case 0x32:
- case 0x33:
- case 0x34:
- case 0x35:
- case 0x36:
- case 0x37:
- if (dreg == (extra & 7))
- fsin_rr (dreg, sreg);
- else
- fsincos_rr (dreg, extra & 7, sreg);
+ case 0x1d: /* FCOS */
+ if (jit_disable.fcos)
+ {
+ FAIL(1);
+ return;
+ }
+
+ dont_care_fflags();
+ src = get_fp_value(opcode, extra);
+ if (src < 0)
+ {
+ FAIL(1); /* Illegal instruction */
+ return;
+ }
+ fcos_rr(reg, src);
+ MAKE_FPSR(reg);
break;
- case 0x38: /* FCMP */
- fmov_rr (FP_RESULT, dreg);
- fsub_rr (FP_RESULT, sreg);
+ case 0x1e: /* FGETEXP */
+ if (jit_disable.fgetexp)
+ {
+ FAIL(1);
+ return;
+ }
+
+ FAIL(1);
return;
- case 0x3a: /* FTST */
- fmov_rr (FP_RESULT, sreg);
+ dont_care_fflags();
+ break;
+ case 0x1f: /* FGETMAN */
+ if (jit_disable.fgetman)
+ {
+ FAIL(1);
+ return;
+ }
+
+ FAIL(1);
return;
- case 0x40: /* FSMOVE */
- if (prec == 1 || !currprefs.fpu_strict) {
- if (sreg != dreg) /* no <EA> */
- fmov_rr (dreg, sreg);
+ dont_care_fflags();
+ break;
+ case 0x20: /* FDIV */
+ case 0x60: /* FSDIV */
+ case 0x64: /* FDDIV */
+ if (jit_disable.fdiv)
+ {
+ FAIL(1);
+ return;
}
- else {
- fmovs_mr (uae_p32(temp_fp), sreg);
- fmovs_rm (dreg, uae_p32(temp_fp));
+
+ dont_care_fflags();
+ src = get_fp_value(opcode, extra);
+ if (src < 0)
+ {
+ FAIL(1); /* Illegal instruction */
+ return;
}
+ fdiv_rr(reg, src);
+ MAKE_FPSR(reg);
break;
- case 0x44: /* FDMOVE */
- if (prec || !currprefs.fpu_strict) {
- if (sreg != dreg) /* no <EA> */
- fmov_rr (dreg, sreg);
+ case 0x21: /* FMOD */
+ if (jit_disable.fmod)
+ {
+ FAIL(1);
+ return;
}
- else {
- fmov_mr (uae_p32(temp_fp), sreg);
- fmov_rm (dreg, uae_p32(temp_fp));
+
+ // FIXME: the quotient byte must be computed
+ dont_care_fflags();
+ src = get_fp_value(opcode, extra);
+ if (src < 0)
+ {
+ FAIL(1); /* Illegal instruction */
+ return;
}
+ frem_rr(reg, src);
+ MAKE_FPSR(reg);
break;
- case 0x41: /* FSSQRT */
- fsqrt_rr (dreg, sreg);
- if (!currprefs.fpu_strict) /* faster, but less strict rounding */
- break;
-#if USE_X86_FPUCW
- if ((regs.fpcr & 0xC0) == 0x40) /* if SINGLE precision */
- break;
-#endif
- fcuts_r (dreg);
- break;
- case 0x45: /* FDSQRT */
- if (!currprefs.fpu_strict) { /* faster, but less strict rounding */
- fsqrt_rr (dreg, sreg);
- break;
+ case 0x22: /* FADD */
+ case 0x62: /* FSADD */
+ case 0x66: /* FDADD */
+ if (jit_disable.fadd)
+ {
+ FAIL(1);
+ return;
}
-#if USE_X86_FPUCW
- if (regs.fpcr & 0xC0) { /* if we don't have EXTENDED precision */
- if ((regs.fpcr & 0xC0) == 0x80) /* if we have DOUBLE */
- fsqrt_rr (dreg, sreg);
- else { /* if we have SINGLE presision, force DOUBLE */
- mov_l_ri (S1, (regs.fpcr & 0x30) | 0x80);
- fldcw_m_indexed (S1, uae_p32(x86_fpucw));
- fsqrt_rr (dreg, sreg);
- mov_l_rm (S1, uae_p32(®s.fpcr));
- and_l_ri (S1, 0xf0); /* restore control word */
- fldcw_m_indexed (S1, uae_p32(x86_fpucw));
- }
- break;
+
+ dont_care_fflags();
+ src = get_fp_value(opcode, extra);
+ if (src < 0)
+ {
+ FAIL(1); /* Illegal instruction */
+ return;
}
-#endif /* in case of EXTENDED precision, just reduce the result to DOUBLE */
- fsqrt_rr (dreg, sreg);
- fcut_r (dreg);
+ fadd_rr(reg, src);
+ MAKE_FPSR(reg);
break;
- case 0x58: /* FSABS */
- fabs_rr (dreg, sreg);
- if (prec != 1 && currprefs.fpu_strict)
- fcuts_r (dreg);
- break;
- case 0x5a: /* FSNEG */
- fneg_rr (dreg, sreg);
- if (prec != 1 && currprefs.fpu_strict)
- fcuts_r (dreg);
+ case 0x23: /* FMUL */
+ case 0x63: /* FSMUL */
+ case 0x67: /* FDMUL */
+ if (jit_disable.fmul)
+ {
+ FAIL(1);
+ return;
+ }
+
+ dont_care_fflags();
+ src = get_fp_value(opcode, extra);
+ if (src < 0)
+ {
+ FAIL(1); /* Illegal instruction */
+ return;
+ }
+ fmul_rr(reg, src);
+ MAKE_FPSR(reg);
break;
- case 0x5c: /* FDABS */
- fabs_rr (dreg, sreg);
- if (!prec && currprefs.fpu_strict)
- fcut_r (dreg);
+ case 0x24: /* FSGLDIV */
+ if (jit_disable.fsgldiv)
+ {
+ FAIL(1);
+ return;
+ }
+
+ dont_care_fflags();
+ src = get_fp_value(opcode, extra);
+ if (src < 0)
+ {
+ FAIL(1); /* Illegal instruction */
+ return;
+ }
+ fdiv_rr(reg, src);
+ MAKE_FPSR(reg);
break;
- case 0x5e: /* FDNEG */
- fneg_rr (dreg, sreg);
- if (!prec && currprefs.fpu_strict)
- fcut_r (dreg);
+ case 0x25: /* FREM */
+ if (jit_disable.frem)
+ {
+ FAIL(1);
+ return;
+ }
+ // gb-- disabled because the quotient byte must be computed
+ // otherwise, free rotation in ClarisWorks doesn't work.
+ FAIL(1);
+ return;
+ dont_care_fflags();
+ src = get_fp_value(opcode, extra);
+ if (src < 0)
+ {
+ FAIL(1); /* Illegal instruction */
+ return;
+ }
+ frem1_rr(reg, src);
+ MAKE_FPSR(reg);
break;
- case 0x62: /* FSADD */
- fadd_rr (dreg, sreg);
- if (!currprefs.fpu_strict) /* faster, but less strict rounding */
- break;
-#if USE_X86_FPUCW
- if ((regs.fpcr & 0xC0) == 0x40) /* if SINGLE precision */
- break;
-#endif
- fcuts_r (dreg);
+ case 0x26: /* FSCALE */
+ if (jit_disable.fscale)
+ {
+ FAIL(1);
+ return;
+ }
+
+ FAIL(1);
+ return;
break;
- case 0x64: /* FDDIV */
- if (!currprefs.fpu_strict) { /* faster, but less strict rounding */
- fdiv_rr (dreg, sreg);
- break;
+ case 0x27: /* FSGLMUL */
+ if (jit_disable.fsglmul)
+ {
+ FAIL(1);
+ return;
}
-#if USE_X86_FPUCW
- if (regs.fpcr & 0xC0) { /* if we don't have EXTENDED precision */
- if ((regs.fpcr & 0xC0) == 0x80) /* if we have DOUBLE */
- fdiv_rr (dreg, sreg);
- else { /* if we have SINGLE presision, force DOUBLE */
- mov_l_ri (S1, (regs.fpcr & 0x30) | 0x80);
- fldcw_m_indexed (S1, uae_p32(x86_fpucw));
- fdiv_rr (dreg, sreg);
- mov_l_rm (S1, uae_p32(®s.fpcr));
- and_l_ri (S1, 0xf0); /* restore control word */
- fldcw_m_indexed (S1, uae_p32(x86_fpucw));
- }
- break;
+
+ dont_care_fflags();
+ src = get_fp_value(opcode, extra);
+ if (src < 0)
+ {
+ FAIL(1); /* Illegal instruction */
+ return;
}
-#endif /* in case of EXTENDED precision, just reduce the result to DOUBLE */
- fdiv_rr (dreg, sreg);
- fcut_r (dreg);
+ fmul_rr(reg, src);
+ MAKE_FPSR(reg);
break;
- case 0x66: /* FDADD */
- if (!currprefs.fpu_strict) { /* faster, but less strict rounding */
- fadd_rr (dreg, sreg);
- break;
+ case 0x28: /* FSUB */
+ case 0x68: /* FSSUB */
+ case 0x6c: /* FDSUB */
+ if (jit_disable.fsub)
+ {
+ FAIL(1);
+ return;
}
-#if USE_X86_FPUCW
- if (regs.fpcr & 0xC0) { /* if we don't have EXTENDED precision */
- if ((regs.fpcr & 0xC0) == 0x80) /* if we have DOUBLE */
- fadd_rr (dreg, sreg);
- else { /* if we have SINGLE presision, force DOUBLE */
- mov_l_ri (S1, (regs.fpcr & 0x30) | 0x80);
- fldcw_m_indexed (S1, uae_p32(x86_fpucw));
- fadd_rr (dreg, sreg);
- mov_l_rm (S1, uae_p32(®s.fpcr));
- and_l_ri (S1, 0xf0); /* restore control word */
- fldcw_m_indexed (S1, uae_p32(x86_fpucw));
- }
- break;
+
+ dont_care_fflags();
+ src = get_fp_value(opcode, extra);
+ if (src < 0)
+ {
+ FAIL(1); /* Illegal instruction */
+ return;
}
-#endif /* in case of EXTENDED precision, just reduce the result to DOUBLE */
- fadd_rr (dreg, sreg);
- fcut_r (dreg);
+ fsub_rr(reg, src);
+ MAKE_FPSR(reg);
break;
- case 0x67: /* FDMUL */
- if (!currprefs.fpu_strict) { /* faster, but less strict rounding */
- fmul_rr (dreg, sreg);
- break;
- }
-#if USE_X86_FPUCW
- if (regs.fpcr & 0xC0) { /* if we don't have EXTENDED precision */
- if ((regs.fpcr & 0xC0) == 0x80) /* if we have DOUBLE */
- fmul_rr (dreg, sreg);
- else { /* if we have SINGLE presision, force DOUBLE */
- mov_l_ri (S1, (regs.fpcr & 0x30) | 0x80);
- fldcw_m_indexed (S1, uae_p32(x86_fpucw));
- fmul_rr (dreg, sreg);
- mov_l_rm (S1, uae_p32(®s.fpcr));
- and_l_ri (S1, 0xf0); /* restore control word */
- fldcw_m_indexed (S1, uae_p32(x86_fpucw));
- }
- break;
+ case 0x30: /* FSINCOS */
+ case 0x31:
+ case 0x32:
+ case 0x33:
+ case 0x34:
+ case 0x35:
+ case 0x36:
+ case 0x37:
+ if (jit_disable.fsincos)
+ {
+ FAIL(1);
+ return;
}
-#endif /* in case of EXTENDED precision, just reduce the result to DOUBLE */
- fmul_rr (dreg, sreg);
- fcut_r (dreg);
+
+ FAIL(1);
+ return;
+ dont_care_fflags();
break;
- case 0x68: /* FSSUB */
- fsub_rr (dreg, sreg);
- if (!currprefs.fpu_strict) /* faster, but less strict rounding */
- break;
-#if USE_X86_FPUCW
- if ((regs.fpcr & 0xC0) == 0x40) /* if SINGLE precision */
- break;
-#endif
- fcuts_r (dreg);
+ case 0x38: /* FCMP */
+ if (jit_disable.fcmp)
+ {
+ FAIL(1);
+ return;
+ }
+
+ src = get_fp_value(opcode, extra);
+ if (src < 0)
+ {
+ FAIL(1); /* Illegal instruction */
+ return;
+ }
+ fmov_rr(FP_RESULT, reg);
+ fsub_rr(FP_RESULT, src); /* Right way? */
break;
- case 0x6c: /* FDSUB */
- if (!currprefs.fpu_strict) { /* faster, but less strict rounding */
- fsub_rr (dreg, sreg);
- break;
+ case 0x3a: /* FTST */
+ if (jit_disable.ftst)
+ {
+ FAIL(1);
+ return;
}
-#if USE_X86_FPUCW
- if (regs.fpcr & 0xC0) { /* if we don't have EXTENDED precision */
- if ((regs.fpcr & 0xC0) == 0x80) /* if we have DOUBLE */
- fsub_rr (dreg, sreg);
- else { /* if we have SINGLE presision, force DOUBLE */
- mov_l_ri (S1, (regs.fpcr & 0x30) | 0x80);
- fldcw_m_indexed (S1, uae_p32(x86_fpucw));
- fsub_rr (dreg, sreg);
- mov_l_rm (S1, uae_p32(®s.fpcr));
- and_l_ri (S1, 0xf0); /* restore control word */
- fldcw_m_indexed (S1, uae_p32(x86_fpucw));
- }
- break;
+
+ src = get_fp_value(opcode, extra);
+ if (src < 0)
+ {
+ FAIL(1); /* Illegal instruction */
+ return;
}
-#endif /* in case of EXTENDED precision, just reduce the result to DOUBLE */
- fsub_rr (dreg, sreg);
- fcut_r (dreg);
+ fmov_rr(FP_RESULT, src);
break;
- default:
- FAIL (1);
+ default:
+ FAIL(1);
return;
+ break;
}
- fmov_rr (FP_RESULT, dreg);
- return;
- default:
- write_log (_T ("Unsupported JIT-FPU instruction: 0x%04x %04x\n"), opcode, extra);
- FAIL (1);
return;
}
+ FAIL(1);
}
-#endif
live.flags_in_flags=VALID;
live.flags_are_important=1;
}
-MENDFUNC(0,live_flags,(void))
MIDFUNC(0,dont_care_flags,(void))
{
live.flags_are_important=0;
}
-MENDFUNC(0,dont_care_flags,(void))
+/*
+ * store the state of the x86 carry bit into regflags.x,
+ * into the position denoted by FLAGBIT_X
+ */
MIDFUNC(0,duplicate_carry,(void))
{
evict(FLAGX);
make_flags_live_internal();
-#ifdef UAE
- COMPCALL(setcc_m)((uintptr)live.state[FLAGX].mem + 1, NATIVE_CC_CS);
-#else
COMPCALL(setcc_m)((uintptr)live.state[FLAGX].mem, NATIVE_CC_CS);
-#endif
log_vwrite(FLAGX);
}
-MENDFUNC(0,duplicate_carry,(void))
-MIDFUNC(0, setcc_for_cntzero, (RR4))
+MIDFUNC(3,setcc_for_cntzero,(RR4 /* cnt */, RR4 data, int size))
{
- uae_u8 * branchadd;
+ uae_u8 *branchadd;
+ uae_u8 *branchadd2;
evict(FLAGX);
make_flags_live_internal();
raw_jz_b_oponly();
branchadd = get_target();
skip_byte();
+
+ /* shift count was non-zero; update also x-flag */
raw_popfl();
- raw_pushfl();
-#ifdef UAE
- COMPCALL(setcc_m)((uintptr)live.state[FLAGX].mem + 1, NATIVE_CC_CS);
-#else
COMPCALL(setcc_m)((uintptr)live.state[FLAGX].mem, NATIVE_CC_CS);
-#endif
log_vwrite(FLAGX);
+ raw_jmp_b_oponly();
+ branchadd2 = get_target();
+ skip_byte();
*branchadd = (uintptr)get_target() - ((uintptr)branchadd + 1);
+
+ /* shift count was zero; need to set Z & N flags since the native flags were unaffected */
raw_popfl();
+ data = readreg(data, size);
+ switch (size)
+ {
+ case 1: raw_test_b_rr(data, data); break;
+ case 2: raw_test_w_rr(data, data); break;
+ case 4: raw_test_l_rr(data, data); break;
+ }
+ unlock2(data);
+ *branchadd2 = (uintptr)get_target() - ((uintptr)branchadd2 + 1);
}
+/*
+ * Set the x86 carry flag from regflags.x, from the position
+ * denoted by FLAGBIT_X
+ */
MIDFUNC(0,restore_carry,(void))
{
if (!have_rat_stall) { /* Not a P6 core, i.e. no partial stalls */
-#ifdef UAE
- bt_l_ri_noclobber(FLAGX, 8);
-#else
- bt_l_ri_noclobber(FLAGX, 0);
-#endif
+ bt_l_ri_noclobber(FLAGX, FLAGBIT_X);
}
else { /* Avoid the stall the above creates.
This is slow on non-P6, though.
*/
-#ifdef UAE
- COMPCALL(rol_w_ri(FLAGX, 8));
+#if FLAGBIT_X >= 8
+ COMPCALL(rol_w_ri(FLAGX, 16 - FLAGBIT_X));
#else
- COMPCALL(rol_b_ri(FLAGX, 8));
+ COMPCALL(rol_b_ri(FLAGX, 8 - FLAGBIT_X));
#endif
isclean(FLAGX);
}
}
-MENDFUNC(0,restore_carry,(void))
MIDFUNC(0,start_needflags,(void))
{
needflags=1;
}
-MENDFUNC(0,start_needflags,(void))
MIDFUNC(0,end_needflags,(void))
{
needflags=0;
}
-MENDFUNC(0,end_needflags,(void))
MIDFUNC(0,make_flags_live,(void))
{
make_flags_live_internal();
}
-MENDFUNC(0,make_flags_live,(void))
MIDFUNC(1,fflags_into_flags,(W2 tmp))
{
clobber_flags();
fflags_into_flags_internal(tmp);
}
-MENDFUNC(1,fflags_into_flags,(W2 tmp))
MIDFUNC(2,bt_l_ri,(RR4 r, IMM i)) /* This is defined as only affecting C */
{
raw_bt_l_ri(r,i);
unlock2(r);
}
-MENDFUNC(2,bt_l_ri,(RR4 r, IMM i)) /* This is defined as only affecting C */
MIDFUNC(2,bt_l_rr,(RR4 r, RR4 b)) /* This is defined as only affecting C */
{
unlock2(r);
unlock2(b);
}
-MENDFUNC(2,bt_l_rr,(RR4 r, RR4 b)) /* This is defined as only affecting C */
MIDFUNC(2,btc_l_ri,(RW4 r, IMM i))
{
raw_btc_l_ri(r,i);
unlock2(r);
}
-MENDFUNC(2,btc_l_ri,(RW4 r, IMM i))
MIDFUNC(2,btc_l_rr,(RW4 r, RR4 b))
{
unlock2(r);
unlock2(b);
}
-MENDFUNC(2,btc_l_rr,(RW4 r, RR4 b))
MIDFUNC(2,btr_l_ri,(RW4 r, IMM i))
{
raw_btr_l_ri(r,i);
unlock2(r);
}
-MENDFUNC(2,btr_l_ri,(RW4 r, IMM i))
MIDFUNC(2,btr_l_rr,(RW4 r, RR4 b))
{
unlock2(r);
unlock2(b);
}
-MENDFUNC(2,btr_l_rr,(RW4 r, RR4 b))
MIDFUNC(2,bts_l_ri,(RW4 r, IMM i))
{
raw_bts_l_ri(r,i);
unlock2(r);
}
-MENDFUNC(2,bts_l_ri,(RW4 r, IMM i))
MIDFUNC(2,bts_l_rr,(RW4 r, RR4 b))
{
unlock2(r);
unlock2(b);
}
-MENDFUNC(2,bts_l_rr,(RW4 r, RR4 b))
MIDFUNC(2,mov_l_rm,(W4 d, IMM s))
{
raw_mov_l_rm(d,s);
unlock2(d);
}
-MENDFUNC(2,mov_l_rm,(W4 d, IMM s))
MIDFUNC(1,call_r,(RR4 r)) /* Clobbering is implicit */
{
raw_inc_sp(STACK_SHADOW_SPACE);
unlock2(r);
}
-MENDFUNC(1,call_r,(RR4 r)) /* Clobbering is implicit */
MIDFUNC(2,sub_l_mi,(IMM d, IMM s))
{
CLOBBER_SUB;
raw_sub_l_mi(d,s) ;
}
-MENDFUNC(2,sub_l_mi,(IMM d, IMM s))
MIDFUNC(2,mov_l_mi,(IMM d, IMM s))
{
CLOBBER_MOV;
raw_mov_l_mi(d,s) ;
}
-MENDFUNC(2,mov_l_mi,(IMM d, IMM s))
MIDFUNC(2,mov_w_mi,(IMM d, IMM s))
{
CLOBBER_MOV;
raw_mov_w_mi(d,s) ;
}
-MENDFUNC(2,mov_w_mi,(IMM d, IMM s))
MIDFUNC(2,mov_b_mi,(IMM d, IMM s))
{
CLOBBER_MOV;
raw_mov_b_mi(d,s) ;
}
-MENDFUNC(2,mov_b_mi,(IMM d, IMM s))
MIDFUNC(2,rol_b_ri,(RW1 r, IMM i))
{
raw_rol_b_ri(r,i);
unlock2(r);
}
-MENDFUNC(2,rol_b_ri,(RW1 r, IMM i))
MIDFUNC(2,rol_w_ri,(RW2 r, IMM i))
{
raw_rol_w_ri(r,i);
unlock2(r);
}
-MENDFUNC(2,rol_w_ri,(RW2 r, IMM i))
MIDFUNC(2,rol_l_ri,(RW4 r, IMM i))
{
raw_rol_l_ri(r,i);
unlock2(r);
}
-MENDFUNC(2,rol_l_ri,(RW4 r, IMM i))
MIDFUNC(2,rol_l_rr,(RW4 d, RR1 r))
{
- if (isconst(r)) {
+ if (isconst(r) && (uae_u8)live.state[r].val != 0) {
COMPCALL(rol_l_ri)(d,(uae_u8)live.state[r].val);
return;
}
CLOBBER_ROL;
r=readreg_specific(r,1,SHIFTCOUNT_NREG);
d=rmw(d,4,4);
- Dif (r!=1) {
- jit_abort("Illegal register %d in raw_rol_b",r);
+ Dif (r!=X86_CL) {
+ jit_abort("Illegal register %d in rol_l_rr",r);
}
raw_rol_l_rr(d,r) ;
unlock2(r);
unlock2(d);
}
-MENDFUNC(2,rol_l_rr,(RW4 d, RR1 r))
MIDFUNC(2,rol_w_rr,(RW2 d, RR1 r))
{ /* Can only do this with r==1, i.e. cl */
- if (isconst(r)) {
+ if (isconst(r) && (uae_u8)live.state[r].val != 0) {
COMPCALL(rol_w_ri)(d,(uae_u8)live.state[r].val);
return;
}
CLOBBER_ROL;
r=readreg_specific(r,1,SHIFTCOUNT_NREG);
d=rmw(d,2,2);
- Dif (r!=1) {
- jit_abort("Illegal register %d in raw_rol_b",r);
+ Dif (r!=X86_CL) {
+ jit_abort("Illegal register %d in rol_w_rr",r);
}
raw_rol_w_rr(d,r) ;
unlock2(r);
unlock2(d);
}
-MENDFUNC(2,rol_w_rr,(RW2 d, RR1 r))
MIDFUNC(2,rol_b_rr,(RW1 d, RR1 r))
{ /* Can only do this with r==1, i.e. cl */
- if (isconst(r)) {
+ if (isconst(r) && (uae_u8)live.state[r].val != 0) {
COMPCALL(rol_b_ri)(d,(uae_u8)live.state[r].val);
return;
}
CLOBBER_ROL;
r=readreg_specific(r,1,SHIFTCOUNT_NREG);
d=rmw(d,1,1);
- Dif (r!=1) {
- jit_abort("Illegal register %d in raw_rol_b",r);
+ Dif (r!=X86_CL) {
+ jit_abort("Illegal register %d in rol_b_rr",r);
}
raw_rol_b_rr(d,r) ;
unlock2(r);
unlock2(d);
}
-MENDFUNC(2,rol_b_rr,(RW1 d, RR1 r))
MIDFUNC(2,shll_l_rr,(RW4 d, RR1 r))
{
- if (isconst(r)) {
+ if (isconst(r) && (uae_u8)live.state[r].val != 0) {
COMPCALL(shll_l_ri)(d,(uae_u8)live.state[r].val);
return;
}
CLOBBER_SHLL;
r=readreg_specific(r,1,SHIFTCOUNT_NREG);
d=rmw(d,4,4);
- Dif (r!=1) {
- jit_abort("Illegal register %d in raw_rol_b",r);
+ Dif (r!=X86_CL) {
+ jit_abort("Illegal register %d in shll_l_rr",r);
}
raw_shll_l_rr(d,r) ;
unlock2(r);
unlock2(d);
}
-MENDFUNC(2,shll_l_rr,(RW4 d, RR1 r))
MIDFUNC(2,shll_w_rr,(RW2 d, RR1 r))
{ /* Can only do this with r==1, i.e. cl */
- if (isconst(r)) {
+ if (isconst(r) && (uae_u8)live.state[r].val != 0) {
COMPCALL(shll_w_ri)(d,(uae_u8)live.state[r].val);
return;
}
CLOBBER_SHLL;
r=readreg_specific(r,1,SHIFTCOUNT_NREG);
d=rmw(d,2,2);
- Dif (r!=1) {
- jit_abort("Illegal register %d in raw_shll_b",r);
+ Dif (r!=X86_CL) {
+ jit_abort("Illegal register %d in shll_w_rr",r);
}
raw_shll_w_rr(d,r) ;
unlock2(r);
unlock2(d);
}
-MENDFUNC(2,shll_w_rr,(RW2 d, RR1 r))
MIDFUNC(2,shll_b_rr,(RW1 d, RR1 r))
{ /* Can only do this with r==1, i.e. cl */
- if (isconst(r)) {
+ if (isconst(r) && (uae_u8)live.state[r].val != 0) {
COMPCALL(shll_b_ri)(d,(uae_u8)live.state[r].val);
return;
}
CLOBBER_SHLL;
r=readreg_specific(r,1,SHIFTCOUNT_NREG);
d=rmw(d,1,1);
- Dif (r!=1) {
- jit_abort("Illegal register %d in raw_shll_b",r);
+ Dif (r!=X86_CL) {
+ jit_abort("Illegal register %d in shll_b_rr",r);
}
raw_shll_b_rr(d,r) ;
unlock2(r);
unlock2(d);
}
-MENDFUNC(2,shll_b_rr,(RW1 d, RR1 r))
MIDFUNC(2,ror_b_ri,(RR1 r, IMM i))
raw_ror_b_ri(r,i);
unlock2(r);
}
-MENDFUNC(2,ror_b_ri,(RR1 r, IMM i))
MIDFUNC(2,ror_w_ri,(RR2 r, IMM i))
{
raw_ror_w_ri(r,i);
unlock2(r);
}
-MENDFUNC(2,ror_w_ri,(RR2 r, IMM i))
MIDFUNC(2,ror_l_ri,(RR4 r, IMM i))
{
raw_ror_l_ri(r,i);
unlock2(r);
}
-MENDFUNC(2,ror_l_ri,(RR4 r, IMM i))
MIDFUNC(2,ror_l_rr,(RR4 d, RR1 r))
{
- if (isconst(r)) {
+ if (isconst(r) && (uae_u8)live.state[r].val != 0) {
COMPCALL(ror_l_ri)(d,(uae_u8)live.state[r].val);
return;
}
unlock2(r);
unlock2(d);
}
-MENDFUNC(2,ror_l_rr,(RR4 d, RR1 r))
MIDFUNC(2,ror_w_rr,(RR2 d, RR1 r))
{
- if (isconst(r)) {
+ if (isconst(r) && (uae_u8)live.state[r].val != 0) {
COMPCALL(ror_w_ri)(d,(uae_u8)live.state[r].val);
return;
}
unlock2(r);
unlock2(d);
}
-MENDFUNC(2,ror_w_rr,(RR2 d, RR1 r))
MIDFUNC(2,ror_b_rr,(RR1 d, RR1 r))
{
- if (isconst(r)) {
+ if (isconst(r) && (uae_u8)live.state[r].val != 0) {
COMPCALL(ror_b_ri)(d,(uae_u8)live.state[r].val);
return;
}
unlock2(r);
unlock2(d);
}
-MENDFUNC(2,ror_b_rr,(RR1 d, RR1 r))
MIDFUNC(2,shrl_l_rr,(RW4 d, RR1 r))
{
- if (isconst(r)) {
+ if (isconst(r) && (uae_u8)live.state[r].val != 0) {
COMPCALL(shrl_l_ri)(d,(uae_u8)live.state[r].val);
return;
}
CLOBBER_SHRL;
r=readreg_specific(r,1,SHIFTCOUNT_NREG);
d=rmw(d,4,4);
- Dif (r!=1) {
- jit_abort("Illegal register %d in raw_rol_b",r);
+ Dif (r!=X86_CL) {
+ jit_abort("Illegal register %d in shrl_l_rr",r);
}
raw_shrl_l_rr(d,r) ;
unlock2(r);
unlock2(d);
}
-MENDFUNC(2,shrl_l_rr,(RW4 d, RR1 r))
MIDFUNC(2,shrl_w_rr,(RW2 d, RR1 r))
{ /* Can only do this with r==1, i.e. cl */
- if (isconst(r)) {
+ if (isconst(r) && (uae_u8)live.state[r].val != 0) {
COMPCALL(shrl_w_ri)(d,(uae_u8)live.state[r].val);
return;
}
CLOBBER_SHRL;
r=readreg_specific(r,1,SHIFTCOUNT_NREG);
d=rmw(d,2,2);
- Dif (r!=1) {
- jit_abort("Illegal register %d in raw_shrl_b",r);
+ Dif (r!=X86_CL) {
+ jit_abort("Illegal register %d in shrl_w_rr",r);
}
raw_shrl_w_rr(d,r) ;
unlock2(r);
unlock2(d);
}
-MENDFUNC(2,shrl_w_rr,(RW2 d, RR1 r))
MIDFUNC(2,shrl_b_rr,(RW1 d, RR1 r))
{ /* Can only do this with r==1, i.e. cl */
- if (isconst(r)) {
+ if (isconst(r) && (uae_u8)live.state[r].val != 0) {
COMPCALL(shrl_b_ri)(d,(uae_u8)live.state[r].val);
return;
}
CLOBBER_SHRL;
r=readreg_specific(r,1,SHIFTCOUNT_NREG);
d=rmw(d,1,1);
- Dif (r!=1) {
- jit_abort("Illegal register %d in raw_shrl_b",r);
+ Dif (r!=X86_CL) {
+ jit_abort("Illegal register %d in shrl_b_rr",r);
}
raw_shrl_b_rr(d,r) ;
unlock2(r);
unlock2(d);
}
-MENDFUNC(2,shrl_b_rr,(RW1 d, RR1 r))
raw_shll_l_ri(r,i);
unlock2(r);
}
-MENDFUNC(2,shll_l_ri,(RW4 r, IMM i))
MIDFUNC(2,shll_w_ri,(RW2 r, IMM i))
{
raw_shll_w_ri(r,i);
unlock2(r);
}
-MENDFUNC(2,shll_w_ri,(RW2 r, IMM i))
MIDFUNC(2,shll_b_ri,(RW1 r, IMM i))
{
raw_shll_b_ri(r,i);
unlock2(r);
}
-MENDFUNC(2,shll_b_ri,(RW1 r, IMM i))
MIDFUNC(2,shrl_l_ri,(RW4 r, IMM i))
{
raw_shrl_l_ri(r,i);
unlock2(r);
}
-MENDFUNC(2,shrl_l_ri,(RW4 r, IMM i))
MIDFUNC(2,shrl_w_ri,(RW2 r, IMM i))
{
raw_shrl_w_ri(r,i);
unlock2(r);
}
-MENDFUNC(2,shrl_w_ri,(RW2 r, IMM i))
MIDFUNC(2,shrl_b_ri,(RW1 r, IMM i))
{
raw_shrl_b_ri(r,i);
unlock2(r);
}
-MENDFUNC(2,shrl_b_ri,(RW1 r, IMM i))
MIDFUNC(2,shra_l_ri,(RW4 r, IMM i))
{
raw_shra_l_ri(r,i);
unlock2(r);
}
-MENDFUNC(2,shra_l_ri,(RW4 r, IMM i))
MIDFUNC(2,shra_w_ri,(RW2 r, IMM i))
{
raw_shra_w_ri(r,i);
unlock2(r);
}
-MENDFUNC(2,shra_w_ri,(RW2 r, IMM i))
MIDFUNC(2,shra_b_ri,(RW1 r, IMM i))
{
raw_shra_b_ri(r,i);
unlock2(r);
}
-MENDFUNC(2,shra_b_ri,(RW1 r, IMM i))
MIDFUNC(2,shra_l_rr,(RW4 d, RR1 r))
{
- if (isconst(r)) {
+ if (isconst(r) && (uae_u8)live.state[r].val != 0) {
COMPCALL(shra_l_ri)(d,(uae_u8)live.state[r].val);
return;
}
CLOBBER_SHRA;
r=readreg_specific(r,1,SHIFTCOUNT_NREG);
d=rmw(d,4,4);
- Dif (r!=1) {
- jit_abort("Illegal register %d in raw_rol_b",r);
+ Dif (r!=X86_CL) {
+ jit_abort("Illegal register %d in shra_l_rr",r);
}
raw_shra_l_rr(d,r) ;
unlock2(r);
unlock2(d);
}
-MENDFUNC(2,shra_l_rr,(RW4 d, RR1 r))
MIDFUNC(2,shra_w_rr,(RW2 d, RR1 r))
{ /* Can only do this with r==1, i.e. cl */
- if (isconst(r)) {
+ if (isconst(r) && (uae_u8)live.state[r].val != 0) {
COMPCALL(shra_w_ri)(d,(uae_u8)live.state[r].val);
return;
}
CLOBBER_SHRA;
r=readreg_specific(r,1,SHIFTCOUNT_NREG);
d=rmw(d,2,2);
- Dif (r!=1) {
- jit_abort("Illegal register %d in raw_shra_b",r);
+ Dif (r!=X86_CL) {
+ jit_abort("Illegal register %d in shra_w_rr",r);
}
raw_shra_w_rr(d,r) ;
unlock2(r);
unlock2(d);
}
-MENDFUNC(2,shra_w_rr,(RW2 d, RR1 r))
MIDFUNC(2,shra_b_rr,(RW1 d, RR1 r))
{ /* Can only do this with r==1, i.e. cl */
- if (isconst(r)) {
+ if (isconst(r) && (uae_u8)live.state[r].val != 0) {
COMPCALL(shra_b_ri)(d,(uae_u8)live.state[r].val);
return;
}
CLOBBER_SHRA;
r=readreg_specific(r,1,SHIFTCOUNT_NREG);
d=rmw(d,1,1);
- Dif (r!=1) {
- jit_abort("Illegal register %d in raw_shra_b",r);
+ Dif (r!=X86_CL) {
+ jit_abort("Illegal register %d in shra_b_rr",r);
}
raw_shra_b_rr(d,r) ;
unlock2(r);
unlock2(d);
}
-MENDFUNC(2,shra_b_rr,(RW1 d, RR1 r))
MIDFUNC(2,setcc,(W1 d, IMM cc))
raw_setcc(d,cc);
unlock2(d);
}
-MENDFUNC(2,setcc,(W1 d, IMM cc))
MIDFUNC(2,setcc_m,(IMM d, IMM cc))
{
CLOBBER_SETCC;
raw_setcc_m(d,cc);
}
-MENDFUNC(2,setcc_m,(IMM d, IMM cc))
MIDFUNC(3,cmov_l_rr,(RW4 d, RR4 s, IMM cc))
{
unlock2(s);
unlock2(d);
}
-MENDFUNC(3,cmov_l_rr,(RW4 d, RR4 s, IMM cc))
MIDFUNC(3,cmov_l_rm,(RW4 d, IMM s, IMM cc))
{
raw_cmov_l_rm(d,s,cc);
unlock2(d);
}
-MENDFUNC(3,cmov_l_rm,(RW4 d, IMM s, IMM cc))
MIDFUNC(2,bsf_l_rr,(W4 d, RR4 s))
{
unlock2(s);
unlock2(d);
}
-MENDFUNC(2,bsf_l_rr,(W4 d, RR4 s))
/* Set the Z flag depending on the value in s. Note that the
value has to be 0 or -1 (or, more precisely, for non-zero
unlock2(tmp);
unlock2(s);
}
-MENDFUNC(2,simulate_bsf,(W4 tmp, RW4 s))
MIDFUNC(2,imul_32_32,(RW4 d, RR4 s))
{
unlock2(s);
unlock2(d);
}
-MENDFUNC(2,imul_32_32,(RW4 d, RR4 s))
MIDFUNC(2,imul_64_32,(RW4 d, RW4 s))
{
unlock2(s);
unlock2(d);
}
-MENDFUNC(2,imul_64_32,(RW4 d, RW4 s))
MIDFUNC(2,mul_64_32,(RW4 d, RW4 s))
{
unlock2(s);
unlock2(d);
}
-MENDFUNC(2,mul_64_32,(RW4 d, RW4 s))
MIDFUNC(2,mul_32_32,(RW4 d, RR4 s))
{
unlock2(s);
unlock2(d);
}
-MENDFUNC(2,mul_32_32,(RW4 d, RR4 s))
#if SIZEOF_VOID_P == 8
MIDFUNC(2,sign_extend_32_rr,(W4 d, RR2 s))
unlock2(s);
}
}
-MENDFUNC(2,sign_extend_32_rr,(W4 d, RR2 s))
#endif
MIDFUNC(2,sign_extend_16_rr,(W4 d, RR2 s))
unlock2(s);
}
}
-MENDFUNC(2,sign_extend_16_rr,(W4 d, RR2 s))
MIDFUNC(2,sign_extend_8_rr,(W4 d, RR1 s))
{
unlock2(s);
}
}
-MENDFUNC(2,sign_extend_8_rr,(W4 d, RR1 s))
MIDFUNC(2,zero_extend_16_rr,(W4 d, RR2 s))
unlock2(s);
}
}
-MENDFUNC(2,zero_extend_16_rr,(W4 d, RR2 s))
MIDFUNC(2,zero_extend_8_rr,(W4 d, RR1 s))
{
unlock2(s);
}
}
-MENDFUNC(2,zero_extend_8_rr,(W4 d, RR1 s))
MIDFUNC(2,mov_b_rr,(W1 d, RR1 s))
{
unlock2(d);
unlock2(s);
}
-MENDFUNC(2,mov_b_rr,(W1 d, RR1 s))
MIDFUNC(2,mov_w_rr,(W2 d, RR2 s))
{
unlock2(d);
unlock2(s);
}
-MENDFUNC(2,mov_w_rr,(W2 d, RR2 s))
MIDFUNC(4,mov_l_rrm_indexed,(W4 d,RR4 baser, RR4 index, IMM factor))
{
unlock2(baser);
unlock2(index);
}
-MENDFUNC(4,mov_l_rrm_indexed,(W4 d,RR4 baser, RR4 index, IMM factor))
MIDFUNC(4,mov_w_rrm_indexed,(W2 d, RR4 baser, RR4 index, IMM factor))
{
unlock2(baser);
unlock2(index);
}
-MENDFUNC(4,mov_w_rrm_indexed,(W2 d, RR4 baser, RR4 index, IMM factor))
MIDFUNC(4,mov_b_rrm_indexed,(W1 d, RR4 baser, RR4 index, IMM factor))
{
unlock2(baser);
unlock2(index);
}
-MENDFUNC(4,mov_b_rrm_indexed,(W1 d, RR4 baser, RR4 index, IMM factor))
MIDFUNC(4,mov_l_mrr_indexed,(RR4 baser, RR4 index, IMM factor, RR4 s))
unlock2(baser);
unlock2(index);
}
-MENDFUNC(4,mov_l_mrr_indexed,(RR4 baser, RR4 index, IMM factor, RR4 s))
MIDFUNC(4,mov_w_mrr_indexed,(RR4 baser, RR4 index, IMM factor, RR2 s))
{
unlock2(baser);
unlock2(index);
}
-MENDFUNC(4,mov_w_mrr_indexed,(RR4 baser, RR4 index, IMM factor, RR2 s))
MIDFUNC(4,mov_b_mrr_indexed,(RR4 baser, RR4 index, IMM factor, RR1 s))
{
unlock2(baser);
unlock2(index);
}
-MENDFUNC(4,mov_b_mrr_indexed,(RR4 baser, RR4 index, IMM factor, RR1 s))
MIDFUNC(5,mov_l_bmrr_indexed,(IMM base, RR4 baser, RR4 index, IMM factor, RR4 s))
unlock2(baser);
unlock2(index);
}
-MENDFUNC(5,mov_l_bmrr_indexed,(IMM base, RR4 baser, RR4 index, IMM factor, RR4 s))
MIDFUNC(5,mov_w_bmrr_indexed,(IMM base, RR4 baser, RR4 index, IMM factor, RR2 s))
{
unlock2(baser);
unlock2(index);
}
-MENDFUNC(5,mov_w_bmrr_indexed,(IMM base, RR4 baser, RR4 index, IMM factor, RR2 s))
MIDFUNC(5,mov_b_bmrr_indexed,(IMM base, RR4 baser, RR4 index, IMM factor, RR1 s))
{
unlock2(baser);
unlock2(index);
}
-MENDFUNC(5,mov_b_bmrr_indexed,(IMM base, RR4 baser, RR4 index, IMM factor, RR1 s))
unlock2(baser);
unlock2(index);
}
-MENDFUNC(5,mov_l_brrm_indexed,(W4 d, IMM base, RR4 baser, RR4 index, IMM factor))
MIDFUNC(5,mov_w_brrm_indexed,(W2 d, IMM base, RR4 baser, RR4 index, IMM factor))
unlock2(baser);
unlock2(index);
}
-MENDFUNC(5,mov_w_brrm_indexed,(W2 d, IMM base, RR4 baser, RR4 index, IMM factor))
MIDFUNC(5,mov_b_brrm_indexed,(W1 d, IMM base, RR4 baser, RR4 index, IMM factor))
unlock2(baser);
unlock2(index);
}
-MENDFUNC(5,mov_b_brrm_indexed,(W1 d, IMM base, RR4 baser, RR4 index, IMM factor))
/* Read a long from base+factor*index */
MIDFUNC(4,mov_l_rm_indexed,(W4 d, IMM base, RR4 index, IMM factor))
unlock2(index);
unlock2(d);
}
-MENDFUNC(4,mov_l_rm_indexed,(W4 d, IMM base, RR4 index, IMM factor))
/* read the long at the address contained in s+offset and store in d */
MIDFUNC(3,mov_l_rR,(W4 d, RR4 s, IMM offset))
unlock2(d);
unlock2(s);
}
-MENDFUNC(3,mov_l_rR,(W4 d, RR4 s, IMM offset))
/* read the word at the address contained in s+offset and store in d */
MIDFUNC(3,mov_w_rR,(W2 d, RR4 s, IMM offset))
unlock2(d);
unlock2(s);
}
-MENDFUNC(3,mov_w_rR,(W2 d, RR4 s, IMM offset))
/* read the word at the address contained in s+offset and store in d */
MIDFUNC(3,mov_b_rR,(W1 d, RR4 s, IMM offset))
unlock2(d);
unlock2(s);
}
-MENDFUNC(3,mov_b_rR,(W1 d, RR4 s, IMM offset))
/* read the long at the address contained in s+offset and store in d */
MIDFUNC(3,mov_l_brR,(W4 d, RR4 s, IMM offset))
unlock2(d);
unlock2(s);
}
-MENDFUNC(3,mov_l_brR,(W4 d, RR4 s, IMM offset))
/* read the word at the address contained in s+offset and store in d */
MIDFUNC(3,mov_w_brR,(W2 d, RR4 s, IMM offset))
unlock2(d);
unlock2(s);
}
-MENDFUNC(3,mov_w_brR,(W2 d, RR4 s, IMM offset))
/* read the word at the address contained in s+offset and store in d */
MIDFUNC(3,mov_b_brR,(W1 d, RR4 s, IMM offset))
unlock2(d);
unlock2(s);
}
-MENDFUNC(3,mov_b_brR,(W1 d, RR4 s, IMM offset))
MIDFUNC(3,mov_l_Ri,(RR4 d, IMM i, IMM offset))
{
raw_mov_l_Ri(d,i,offset);
unlock2(d);
}
-MENDFUNC(3,mov_l_Ri,(RR4 d, IMM i, IMM offset))
MIDFUNC(3,mov_w_Ri,(RR4 d, IMM i, IMM offset))
{
raw_mov_w_Ri(d,i,offset);
unlock2(d);
}
-MENDFUNC(3,mov_w_Ri,(RR4 d, IMM i, IMM offset))
MIDFUNC(3,mov_b_Ri,(RR4 d, IMM i, IMM offset))
{
raw_mov_b_Ri(d,i,offset);
unlock2(d);
}
-MENDFUNC(3,mov_b_Ri,(RR4 d, IMM i, IMM offset))
/* Warning! OFFSET is byte sized only! */
MIDFUNC(3,mov_l_Rr,(RR4 d, RR4 s, IMM offset))
unlock2(d);
unlock2(s);
}
-MENDFUNC(3,mov_l_Rr,(RR4 d, RR4 s, IMM offset))
MIDFUNC(3,mov_w_Rr,(RR4 d, RR2 s, IMM offset))
{
unlock2(d);
unlock2(s);
}
-MENDFUNC(3,mov_w_Rr,(RR4 d, RR2 s, IMM offset))
MIDFUNC(3,mov_b_Rr,(RR4 d, RR1 s, IMM offset))
{
unlock2(d);
unlock2(s);
}
-MENDFUNC(3,mov_b_Rr,(RR4 d, RR1 s, IMM offset))
MIDFUNC(3,lea_l_brr,(W4 d, RR4 s, IMM offset))
{
unlock2(d);
unlock2(s);
}
-MENDFUNC(3,lea_l_brr,(W4 d, RR4 s, IMM offset))
MIDFUNC(5,lea_l_brr_indexed,(W4 d, RR4 s, RR4 index, IMM factor, IMM offset))
{
unlock2(index);
unlock2(s);
}
-MENDFUNC(5,lea_l_brr_indexed,(W4 d, RR4 s, RR4 index, IMM factor, IMM offset))
MIDFUNC(4,lea_l_rr_indexed,(W4 d, RR4 s, RR4 index, IMM factor))
{
unlock2(index);
unlock2(s);
}
-MENDFUNC(4,lea_l_rr_indexed,(W4 d, RR4 s, RR4 index, IMM factor))
/* write d to the long at the address contained in s+offset */
MIDFUNC(3,mov_l_bRr,(RR4 d, RR4 s, IMM offset))
unlock2(d);
unlock2(s);
}
-MENDFUNC(3,mov_l_bRr,(RR4 d, RR4 s, IMM offset))
/* write the word at the address contained in s+offset and store in d */
MIDFUNC(3,mov_w_bRr,(RR4 d, RR2 s, IMM offset))
unlock2(d);
unlock2(s);
}
-MENDFUNC(3,mov_w_bRr,(RR4 d, RR2 s, IMM offset))
MIDFUNC(3,mov_b_bRr,(RR4 d, RR1 s, IMM offset))
{
unlock2(d);
unlock2(s);
}
-MENDFUNC(3,mov_b_bRr,(RR4 d, RR1 s, IMM offset))
MIDFUNC(1,mid_bswap_32,(RW4 r))
{
raw_bswap_32(r);
unlock2(r);
}
-MENDFUNC(1,mid_bswap_32,(RW4 r))
MIDFUNC(1,mid_bswap_16,(RW2 r))
{
raw_bswap_16(r);
unlock2(r);
}
-MENDFUNC(1,mid_bswap_16,(RW2 r))
jit_log2("Added %d to nreg %d(%d), now holds %d regs", d,s,live.state[d].realind,live.nat[s].nholds);
unlock2(s);
}
-MENDFUNC(2,mov_l_rr,(W4 d, RR4 s))
MIDFUNC(2,mov_l_mr,(IMM d, RR4 s))
{
raw_mov_l_mr(d,s);
unlock2(s);
}
-MENDFUNC(2,mov_l_mr,(IMM d, RR4 s))
MIDFUNC(2,mov_w_mr,(IMM d, RR2 s))
raw_mov_w_mr(d,s);
unlock2(s);
}
-MENDFUNC(2,mov_w_mr,(IMM d, RR2 s))
MIDFUNC(2,mov_w_rm,(W2 d, IMM s))
{
raw_mov_w_rm(d,s);
unlock2(d);
}
-MENDFUNC(2,mov_w_rm,(W2 d, IMM s))
MIDFUNC(2,mov_b_mr,(IMM d, RR1 s))
{
raw_mov_b_mr(d,s);
unlock2(s);
}
-MENDFUNC(2,mov_b_mr,(IMM d, RR1 s))
MIDFUNC(2,mov_b_rm,(W1 d, IMM s))
{
raw_mov_b_rm(d,s);
unlock2(d);
}
-MENDFUNC(2,mov_b_rm,(W1 d, IMM s))
MIDFUNC(2,mov_l_ri,(W4 d, IMM s))
{
set_const(d,s);
return;
}
-MENDFUNC(2,mov_l_ri,(W4 d, IMM s))
MIDFUNC(2,mov_w_ri,(W2 d, IMM s))
{
raw_mov_w_ri(d,s);
unlock2(d);
}
-MENDFUNC(2,mov_w_ri,(W2 d, IMM s))
MIDFUNC(2,mov_b_ri,(W1 d, IMM s))
{
raw_mov_b_ri(d,s);
unlock2(d);
}
-MENDFUNC(2,mov_b_ri,(W1 d, IMM s))
MIDFUNC(2,add_l_mi,(IMM d, IMM s))
{
CLOBBER_ADD;
- raw_add_l_mi(d,s) ;
+ raw_add_l_mi(d,s);
}
-MENDFUNC(2,add_l_mi,(IMM d, IMM s))
MIDFUNC(2,add_w_mi,(IMM d, IMM s))
{
CLOBBER_ADD;
- raw_add_w_mi(d,s) ;
+ raw_add_w_mi(d,s);
}
-MENDFUNC(2,add_w_mi,(IMM d, IMM s))
MIDFUNC(2,add_b_mi,(IMM d, IMM s))
{
CLOBBER_ADD;
- raw_add_b_mi(d,s) ;
+ raw_add_b_mi(d,s);
}
-MENDFUNC(2,add_b_mi,(IMM d, IMM s))
MIDFUNC(2,test_l_ri,(RR4 d, IMM i))
{
raw_test_l_ri(d,i);
unlock2(d);
}
-MENDFUNC(2,test_l_ri,(RR4 d, IMM i))
MIDFUNC(2,test_l_rr,(RR4 d, RR4 s))
{
unlock2(d);
unlock2(s);
}
-MENDFUNC(2,test_l_rr,(RR4 d, RR4 s))
MIDFUNC(2,test_w_rr,(RR2 d, RR2 s))
{
unlock2(d);
unlock2(s);
}
-MENDFUNC(2,test_w_rr,(RR2 d, RR2 s))
MIDFUNC(2,test_b_rr,(RR1 d, RR1 s))
{
unlock2(d);
unlock2(s);
}
-MENDFUNC(2,test_b_rr,(RR1 d, RR1 s))
+MIDFUNC(2,test_b_mi,(IMM d, IMM s))
+{
+ CLOBBER_TEST;
+ raw_test_b_mi(d,s);
+}
MIDFUNC(2,and_l_ri,(RW4 d, IMM i))
{
raw_and_l_ri(d,i);
unlock2(d);
}
-MENDFUNC(2,and_l_ri,(RW4 d, IMM i))
MIDFUNC(2,and_l,(RW4 d, RR4 s))
{
unlock2(d);
unlock2(s);
}
-MENDFUNC(2,and_l,(RW4 d, RR4 s))
MIDFUNC(2,and_w,(RW2 d, RR2 s))
{
unlock2(d);
unlock2(s);
}
-MENDFUNC(2,and_w,(RW2 d, RR2 s))
MIDFUNC(2,and_b,(RW1 d, RR1 s))
{
unlock2(d);
unlock2(s);
}
-MENDFUNC(2,and_b,(RW1 d, RR1 s))
// gb-- used for making an fpcr value in compemu_fpp.cpp
MIDFUNC(2,or_l_rm,(RW4 d, IMM s))
raw_or_l_rm(d,s);
unlock2(d);
}
-MENDFUNC(2,or_l_rm,(RW4 d, IMM s))
MIDFUNC(2,or_l_ri,(RW4 d, IMM i))
{
raw_or_l_ri(d,i);
unlock2(d);
}
-MENDFUNC(2,or_l_ri,(RW4 d, IMM i))
MIDFUNC(2,or_l,(RW4 d, RR4 s))
{
unlock2(d);
unlock2(s);
}
-MENDFUNC(2,or_l,(RW4 d, RR4 s))
MIDFUNC(2,or_w,(RW2 d, RR2 s))
{
unlock2(d);
unlock2(s);
}
-MENDFUNC(2,or_w,(RW2 d, RR2 s))
MIDFUNC(2,or_b,(RW1 d, RR1 s))
{
unlock2(d);
unlock2(s);
}
-MENDFUNC(2,or_b,(RW1 d, RR1 s))
MIDFUNC(2,adc_l,(RW4 d, RR4 s))
{
unlock2(d);
unlock2(s);
}
-MENDFUNC(2,adc_l,(RW4 d, RR4 s))
MIDFUNC(2,adc_w,(RW2 d, RR2 s))
{
unlock2(d);
unlock2(s);
}
-MENDFUNC(2,adc_w,(RW2 d, RR2 s))
MIDFUNC(2,adc_b,(RW1 d, RR1 s))
{
unlock2(d);
unlock2(s);
}
-MENDFUNC(2,adc_b,(RW1 d, RR1 s))
MIDFUNC(2,add_l,(RW4 d, RR4 s))
{
unlock2(d);
unlock2(s);
}
-MENDFUNC(2,add_l,(RW4 d, RR4 s))
MIDFUNC(2,add_w,(RW2 d, RR2 s))
{
unlock2(d);
unlock2(s);
}
-MENDFUNC(2,add_w,(RW2 d, RR2 s))
MIDFUNC(2,add_b,(RW1 d, RR1 s))
{
unlock2(d);
unlock2(s);
}
-MENDFUNC(2,add_b,(RW1 d, RR1 s))
MIDFUNC(2,sub_l_ri,(RW4 d, IMM i))
{
raw_sub_l_ri(d,i);
unlock2(d);
}
-MENDFUNC(2,sub_l_ri,(RW4 d, IMM i))
MIDFUNC(2,sub_w_ri,(RW2 d, IMM i))
{
raw_sub_w_ri(d,i);
unlock2(d);
}
-MENDFUNC(2,sub_w_ri,(RW2 d, IMM i))
MIDFUNC(2,sub_b_ri,(RW1 d, IMM i))
{
unlock2(d);
}
-MENDFUNC(2,sub_b_ri,(RW1 d, IMM i))
MIDFUNC(2,add_l_ri,(RW4 d, IMM i))
{
raw_add_l_ri(d,i);
unlock2(d);
}
-MENDFUNC(2,add_l_ri,(RW4 d, IMM i))
MIDFUNC(2,add_w_ri,(RW2 d, IMM i))
{
raw_add_w_ri(d,i);
unlock2(d);
}
-MENDFUNC(2,add_w_ri,(RW2 d, IMM i))
MIDFUNC(2,add_b_ri,(RW1 d, IMM i))
{
unlock2(d);
}
-MENDFUNC(2,add_b_ri,(RW1 d, IMM i))
MIDFUNC(2,sbb_l,(RW4 d, RR4 s))
{
unlock2(d);
unlock2(s);
}
-MENDFUNC(2,sbb_l,(RW4 d, RR4 s))
MIDFUNC(2,sbb_w,(RW2 d, RR2 s))
{
unlock2(d);
unlock2(s);
}
-MENDFUNC(2,sbb_w,(RW2 d, RR2 s))
MIDFUNC(2,sbb_b,(RW1 d, RR1 s))
{
unlock2(d);
unlock2(s);
}
-MENDFUNC(2,sbb_b,(RW1 d, RR1 s))
MIDFUNC(2,sub_l,(RW4 d, RR4 s))
{
unlock2(d);
unlock2(s);
}
-MENDFUNC(2,sub_l,(RW4 d, RR4 s))
MIDFUNC(2,sub_w,(RW2 d, RR2 s))
{
unlock2(d);
unlock2(s);
}
-MENDFUNC(2,sub_w,(RW2 d, RR2 s))
MIDFUNC(2,sub_b,(RW1 d, RR1 s))
{
unlock2(d);
unlock2(s);
}
-MENDFUNC(2,sub_b,(RW1 d, RR1 s))
MIDFUNC(2,cmp_l,(RR4 d, RR4 s))
{
unlock2(d);
unlock2(s);
}
-MENDFUNC(2,cmp_l,(RR4 d, RR4 s))
MIDFUNC(2,cmp_l_ri,(RR4 r, IMM i))
{
raw_cmp_l_ri(r,i);
unlock2(r);
}
-MENDFUNC(2,cmp_l_ri,(RR4 r, IMM i))
MIDFUNC(2,cmp_w,(RR2 d, RR2 s))
{
unlock2(d);
unlock2(s);
}
-MENDFUNC(2,cmp_w,(RR2 d, RR2 s))
MIDFUNC(2,cmp_b,(RR1 d, RR1 s))
{
unlock2(d);
unlock2(s);
}
-MENDFUNC(2,cmp_b,(RR1 d, RR1 s))
MIDFUNC(2,xor_l,(RW4 d, RR4 s))
unlock2(d);
unlock2(s);
}
-MENDFUNC(2,xor_l,(RW4 d, RR4 s))
MIDFUNC(2,xor_w,(RW2 d, RR2 s))
{
unlock2(d);
unlock2(s);
}
-MENDFUNC(2,xor_w,(RW2 d, RR2 s))
MIDFUNC(2,xor_b,(RW1 d, RR1 s))
{
unlock2(d);
unlock2(s);
}
-MENDFUNC(2,xor_b,(RW1 d, RR1 s))
+#ifdef UAE
MIDFUNC(5,call_r_11,(W4 out1, RR4 r, RR4 in1, IMM osize, IMM isize))
{
clobber_flags();
live.state[out1].dirtysize=osize;
set_status(out1,DIRTY);
}
-MENDFUNC(5,call_r_11,(W4 out1, RR4 r, RR4 in1, IMM osize, IMM isize))
+#endif
+#if defined(UAE)
MIDFUNC(5,call_r_02,(RR4 r, RR4 in1, RR4 in2, IMM isize1, IMM isize2))
{
clobber_flags();
raw_inc_sp(8);
#endif
}
-MENDFUNC(5,call_r_02,(RR4 r, RR4 in1, RR4 in2, IMM isize1, IMM isize2))
+#endif
/* forget_about() takes a mid-layer register */
MIDFUNC(1,forget_about,(W4 r))
live.state[r].val=0;
set_status(r,UNDEF);
}
-MENDFUNC(1,forget_about,(W4 r))
MIDFUNC(0,nop,(void))
{
raw_emit_nop();
}
-MENDFUNC(0,nop,(void))
MIDFUNC(1,f_forget_about,(FW r))
{
f_disassociate(r);
live.fate[r].status=UNDEF;
}
-MENDFUNC(1,f_forget_about,(FW r))
MIDFUNC(1,fmov_pi,(FW r))
{
raw_fmov_pi(r);
f_unlock(r);
}
-MENDFUNC(1,fmov_pi,(FW r))
MIDFUNC(1,fmov_log10_2,(FW r))
{
raw_fmov_log10_2(r);
f_unlock(r);
}
-MENDFUNC(1,fmov_log10_2,(FW r))
MIDFUNC(1,fmov_log2_e,(FW r))
{
raw_fmov_log2_e(r);
f_unlock(r);
}
-MENDFUNC(1,fmov_log2_e,(FW r))
MIDFUNC(1,fmov_loge_2,(FW r))
{
raw_fmov_loge_2(r);
f_unlock(r);
}
-MENDFUNC(1,fmov_loge_2,(FW r))
MIDFUNC(1,fmov_1,(FW r))
{
raw_fmov_1(r);
f_unlock(r);
}
-MENDFUNC(1,fmov_1,(FW r))
MIDFUNC(1,fmov_0,(FW r))
{
raw_fmov_0(r);
f_unlock(r);
}
-MENDFUNC(1,fmov_0,(FW r))
-MIDFUNC(2,fmov_rm,(FW r, MEMR m))
+MIDFUNC(2,fmov_rm,(FW r, MEMPTRR m))
{
r=f_writereg(r);
raw_fmov_rm(r,m);
f_unlock(r);
}
-MENDFUNC(2,fmov_rm,(FW r, MEMR m))
-MIDFUNC(2,fmovi_rm,(FW r, MEMR m))
+MIDFUNC(2,fmovi_rm,(FW r, MEMPTRR m))
{
r=f_writereg(r);
raw_fmovi_rm(r,m);
f_unlock(r);
}
-MENDFUNC(2,fmovi_rm,(FW r, MEMR m))
-MIDFUNC(2,fmovi_mr,(MEMW m, FR r))
+MIDFUNC(2,fmovi_mr,(MEMPTRW m, FR r))
{
r=f_readreg(r);
raw_fmovi_mr(m,r);
f_unlock(r);
}
-MENDFUNC(2,fmovi_mr,(MEMW m, FR r))
-MIDFUNC(3,fmovi_mrb,(MEMW m, FR r, double *bounds))
+MIDFUNC(3,fmovi_mrb,(MEMPTRW m, FR r, double *bounds))
{
r=f_readreg(r);
raw_fmovi_mrb(m,r,bounds);
f_unlock(r);
}
-MENDFUNC(3,fmovi_mrb,(MEMW m, FR r, double *bounds))
-MIDFUNC(2,fmovs_rm,(FW r, MEMR m))
+MIDFUNC(2,fmovs_rm,(FW r, MEMPTRR m))
{
r=f_writereg(r);
raw_fmovs_rm(r,m);
f_unlock(r);
}
-MENDFUNC(2,fmovs_rm,(FW r, MEMR m))
-MIDFUNC(2,fmovs_mr,(MEMW m, FR r))
+MIDFUNC(2,fmovs_mr,(MEMPTRW m, FR r))
{
r=f_readreg(r);
raw_fmovs_mr(m,r);
f_unlock(r);
}
-MENDFUNC(2,fmovs_mr,(MEMW m, FR r))
MIDFUNC(1,fcuts_r,(FRW r))
{
raw_fcuts_r(r);
f_unlock(r);
}
-MENDFUNC(1,fcuts_r,(FRW r))
MIDFUNC(1,fcut_r,(FRW r))
{
raw_fcut_r(r);
f_unlock(r);
}
-MENDFUNC(1,fcut_r,(FRW r))
-MIDFUNC(2,fmov_ext_mr,(MEMW m, FR r))
+MIDFUNC(2,fmov_ext_mr,(MEMPTRW m, FR r))
{
r=f_readreg(r);
raw_fmov_ext_mr(m,r);
f_unlock(r);
}
-MENDFUNC(2,fmov_ext_mr,(MEMW m, FR r))
-MIDFUNC(2,fmov_mr,(MEMW m, FR r))
+MIDFUNC(2,fmov_mr,(MEMPTRW m, FR r))
{
r=f_readreg(r);
raw_fmov_mr(m,r);
f_unlock(r);
}
-MENDFUNC(2,fmov_mr,(MEMW m, FR r))
-MIDFUNC(2,fmov_ext_rm,(FW r, MEMR m))
+MIDFUNC(2,fmov_ext_rm,(FW r, MEMPTRR m))
{
r=f_writereg(r);
raw_fmov_ext_rm(r,m);
f_unlock(r);
}
-MENDFUNC(2,fmov_ext_rm,(FW r, MEMR m))
MIDFUNC(2,fmov_rr,(FW d, FR s))
{
f_unlock(d);
#endif
}
-MENDFUNC(2,fmov_rr,(FW d, FR s))
MIDFUNC(2,fldcw_m_indexed,(RR4 index, IMM base))
{
raw_fldcw_m_indexed(index,base);
unlock2(index);
}
-MENDFUNC(2,fldcw_m_indexed,(RR4 index, IMM base))
MIDFUNC(1,ftst_r,(FR r))
{
raw_ftst_r(r);
f_unlock(r);
}
-MENDFUNC(1,ftst_r,(FR r))
MIDFUNC(0,dont_care_fflags,(void))
{
f_disassociate(FP_RESULT);
}
-MENDFUNC(0,dont_care_fflags,(void))
MIDFUNC(2,fsqrt_rr,(FW d, FR s))
{
f_unlock(s);
f_unlock(d);
}
-MENDFUNC(2,fsqrt_rr,(FW d, FR s))
MIDFUNC(2,fabs_rr,(FW d, FR s))
{
f_unlock(s);
f_unlock(d);
}
-MENDFUNC(2,fabs_rr,(FW d, FR s))
MIDFUNC(2,fgetexp_rr,(FW d, FR s))
{
f_unlock(s);
f_unlock(d);
}
-MENDFUNC(2,fgetexp_rr,(FW d, FR s))
MIDFUNC(2,fgetman_rr,(FW d, FR s))
{
f_unlock(s);
f_unlock(d);
}
-MENDFUNC(2,fgetman_rr,(FW d, FR s))
MIDFUNC(2,fsin_rr,(FW d, FR s))
{
f_unlock(s);
f_unlock(d);
}
-MENDFUNC(2,fsin_rr,(FW d, FR s))
MIDFUNC(2,fcos_rr,(FW d, FR s))
{
f_unlock(s);
f_unlock(d);
}
-MENDFUNC(2,fcos_rr,(FW d, FR s))
MIDFUNC(2,ftan_rr,(FW d, FR s))
{
f_unlock(s);
f_unlock(d);
}
-MENDFUNC(2,ftan_rr,(FW d, FR s))
MIDFUNC(3,fsincos_rr,(FW d, FW c, FR s))
{
f_unlock(d);
f_unlock(c);
}
-MENDFUNC(3,fsincos_rr,(FW d, FW c, FR s))
MIDFUNC(2,fscale_rr,(FRW d, FR s))
{
f_unlock(s);
f_unlock(d);
}
-MENDFUNC(2,fscale_rr,(FRW d, FR s))
MIDFUNC(2,ftwotox_rr,(FW d, FR s))
{
f_unlock(s);
f_unlock(d);
}
-MENDFUNC(2,ftwotox_rr,(FW d, FR s))
MIDFUNC(2,fetox_rr,(FW d, FR s))
{
f_unlock(s);
f_unlock(d);
}
-MENDFUNC(2,fetox_rr,(FW d, FR s))
MIDFUNC(2,frndint_rr,(FW d, FR s))
{
f_unlock(s);
f_unlock(d);
}
-MENDFUNC(2,frndint_rr,(FW d, FR s))
MIDFUNC(2,fetoxM1_rr,(FW d, FR s))
{
f_unlock(s);
f_unlock(d);
}
-MENDFUNC(2,fetoxM1_rr,(FW d, FR s))
MIDFUNC(2,ftentox_rr,(FW d, FR s))
{
f_unlock(s);
f_unlock(d);
}
-MENDFUNC(2,ftentox_rr,(FW d, FR s))
MIDFUNC(2,flog2_rr,(FW d, FR s))
{
f_unlock(s);
f_unlock(d);
}
-MENDFUNC(2,flog2_rr,(FW d, FR s))
MIDFUNC(2,flogN_rr,(FW d, FR s))
{
f_unlock(s);
f_unlock(d);
}
-MENDFUNC(2,flogN_rr,(FW d, FR s))
MIDFUNC(2,flogNP1_rr,(FW d, FR s))
{
f_unlock(s);
f_unlock(d);
}
-MENDFUNC(2,flogNP1_rr,(FW d, FR s))
MIDFUNC(2,flog10_rr,(FW d, FR s))
{
f_unlock(s);
f_unlock(d);
}
-MENDFUNC(2,flog10_rr,(FW d, FR s))
MIDFUNC(2,fasin_rr,(FW d, FR s))
{
f_unlock(s);
f_unlock(d);
}
-MENDFUNC(2,fasin_rr,(FW d, FR s))
MIDFUNC(2,facos_rr,(FW d, FR s))
{
f_unlock(s);
f_unlock(d);
}
-MENDFUNC(2,facos_rr,(FW d, FR s))
MIDFUNC(2,fatan_rr,(FW d, FR s))
{
f_unlock(s);
f_unlock(d);
}
-MENDFUNC(2,fatan_rr,(FW d, FR s))
MIDFUNC(2,fatanh_rr,(FW d, FR s))
{
f_unlock(s);
f_unlock(d);
}
-MENDFUNC(2,fatanh_rr,(FW d, FR s))
MIDFUNC(2,fsinh_rr,(FW d, FR s))
{
f_unlock(s);
f_unlock(d);
}
-MENDFUNC(2,fsinh_rr,(FW d, FR s))
MIDFUNC(2,fcosh_rr,(FW d, FR s))
{
f_unlock(s);
f_unlock(d);
}
-MENDFUNC(2,fcosh_rr,(FW d, FR s))
MIDFUNC(2,ftanh_rr,(FW d, FR s))
{
f_unlock(s);
f_unlock(d);
}
-MENDFUNC(2,ftanh_rr,(FW d, FR s))
MIDFUNC(2,fneg_rr,(FW d, FR s))
{
f_unlock(s);
f_unlock(d);
}
-MENDFUNC(2,fneg_rr,(FW d, FR s))
MIDFUNC(2,fadd_rr,(FRW d, FR s))
{
f_unlock(s);
f_unlock(d);
}
-MENDFUNC(2,fadd_rr,(FRW d, FR s))
MIDFUNC(2,fsub_rr,(FRW d, FR s))
{
f_unlock(s);
f_unlock(d);
}
-MENDFUNC(2,fsub_rr,(FRW d, FR s))
MIDFUNC(2,fcmp_rr,(FR d, FR s))
{
f_unlock(s);
f_unlock(d);
}
-MENDFUNC(2,fcmp_rr,(FR d, FR s))
MIDFUNC(2,fdiv_rr,(FRW d, FR s))
{
f_unlock(s);
f_unlock(d);
}
-MENDFUNC(2,fdiv_rr,(FRW d, FR s))
MIDFUNC(2,frem_rr,(FRW d, FR s))
{
f_unlock(s);
f_unlock(d);
}
-MENDFUNC(2,frem_rr,(FRW d, FR s))
MIDFUNC(2,frem1_rr,(FRW d, FR s))
{
f_unlock(s);
f_unlock(d);
}
-MENDFUNC(2,frem1_rr,(FRW d, FR s))
MIDFUNC(2,fmul_rr,(FRW d, FR s))
{
f_unlock(s);
f_unlock(d);
}
-MENDFUNC(2,fmul_rr,(FRW d, FR s))
#ifdef __GNUC__
static inline void emit_jmp_target(uae_u32 a) {
emit_long(a-((uintptr)target+4));
}
+
+
+void compemu_bkpt(void)
+{
+ emit_byte(0xcc);
+}
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));
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));
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));
#ifdef JIT
#ifdef UAE
+#define bug write_log
#include "options.h"
#include "events.h"
-#include "memory.h"
+#include "uae/memory.h"
#include "custom.h"
#else
#include "cpu_emulation.h"
#include "comptbl.h"
#ifdef UAE
#include "compemu.h"
+#ifdef FSUAE
+#include "codegen_udis86.h"
+#endif
#else
#include "compiler/compemu.h"
#include "fpu/fpu.h"
#include "fpu/flags.h"
#include "parameters.h"
+static void build_comp(void);
+#endif
+#ifndef UAE
+#include "verify.h"
#endif
#ifdef UAE
+#ifdef FSUAE
+#include "uae/fs.h"
+#endif
#include "uae/log.h"
+#if defined(__pie__) || defined (__PIE__)
+#error Position-independent code (PIE) cannot be used with JIT
+#endif
+
#include "uae/vm.h"
#define VM_PAGE_READ UAE_VM_READ
#define VM_PAGE_WRITE UAE_VM_WRITE
#define FIXED_ADDRESSING 1
#endif
-#define SAHF_SETO_PROFITABLE
-
// %%% BRIAN KING WAS HERE %%%
extern bool canbang;
return 1;
#else
int distrust = value;
+#ifdef FSUAE
+ switch (value) {
+ case 0: distrust = 0; break;
+ case 1: distrust = 1; break;
+ case 2: distrust = ((start_pc & 0xF80000) == 0xF80000); break;
+ case 3: distrust = !have_done_picasso; break;
+ default: abort();
+ }
+#endif
return distrust;
#endif
}
#ifdef RECORD_REGISTER_USAGE
static uint64 reg_count[16];
-static int reg_count_local[16];
+static uint64 reg_count_local[16];
static int reg_count_compare(const void *ap, const void *bp)
{
/* defined in uae.h */
#else
// External variables
-// newcpu.cpp
-extern int quit_program;
#endif
// gb-- Extra data for Basilisk II/JIT
#ifdef JIT_DEBUG
-static bool JITDebug = false; // Enable runtime disassemblers through mon?
+#define JITDebug bx_options.jit.jitdebug // Enable runtime disassemblers through mon?
#else
-const bool JITDebug = false; // Don't use JIT debug mode at all
+#define JITDebug false // Don't use JIT debug mode at all
#endif
#if USE_INLINING
#ifdef UAE
const bool follow_const_jumps = false;
#endif
-const uae_u32 MIN_CACHE_SIZE = 1024; // Minimal translation cache size (1 MB)
static uae_u32 cache_size = 0; // Size of total cache allocated for compiled blocks
static uae_u32 current_cache_size = 0; // Cache grows upwards: how much has been consumed already
static bool lazy_flush = true; // Flag: lazy translation cache invalidation
+// Flag: compile FPU instructions ?
#ifdef UAE
#ifdef USE_JIT_FPU
#define avoid_fpu (!currprefs.compfpu)
#define avoid_fpu (true)
#endif
#else
-static bool avoid_fpu = true; // Flag: compile FPU instructions ?
+#ifdef USE_JIT_FPU
+#define avoid_fpu (!bx_options.jit.jitfpu)
+#else
+#define avoid_fpu (true)
+#endif
#endif
static bool have_cmov = false; // target has CMOV instructions ?
static bool have_rat_stall = true; // target has partial register stalls ?
};
#ifdef UAE
-/* FIXME: op_properties is currently in compemu.h */
-
op_properties prop[65536];
-
-static inline bool is_const_jump(uae_u32 opcode)
-{
- return prop[opcode].is_const_jump != 0;
-}
#else
-struct op_properties {
- uae_u8 use_flags;
- uae_u8 set_flags;
- uae_u8 is_addx;
- uae_u8 cflow;
-};
static op_properties prop[65536];
static inline int end_block(uae_u32 opcode)
{
return (prop[opcode].cflow & fl_end_block);
}
+#endif
static inline bool is_const_jump(uae_u32 opcode)
{
}
#endif
-#endif
-
static inline unsigned int cft_map (unsigned int f)
{
#ifdef UAE
+#if !defined(HAVE_GET_WORD_UNSWAPPED)
return f;
+#else
+ return do_byteswap_16(f);
+#endif
#else
#if !defined(HAVE_GET_WORD_UNSWAPPED) || defined(FULLMMU)
return f;
static int branch_cc;
static int redo_current_block;
+#ifdef UAE
+int segvcount=0;
+#endif
static uae_u8* current_compile_p=NULL;
static uae_u8* max_compile_start;
static uae_u8* compiled_code=NULL;
#ifdef NOFLAGS_SUPPORT
/* 68040 */
-extern const struct cputbl op_smalltbl_0_nf[];
+extern const struct cputbl op_smalltbl_0[];
#endif
extern const struct comptbl op_smalltbl_0_comp_nf[];
extern const struct comptbl op_smalltbl_0_comp_ff[];
#ifdef NOFLAGS_SUPPORT
/* 68020 + 68881 */
-extern const struct cputbl op_smalltbl_1_nf[];
+extern const struct cputbl op_smalltbl_1[];
/* 68020 */
-extern const struct cputbl op_smalltbl_2_nf[];
+extern const struct cputbl op_smalltbl_2[];
/* 68010 */
-extern const struct cputbl op_smalltbl_3_nf[];
+extern const struct cputbl op_smalltbl_3[];
/* 68000 */
-extern const struct cputbl op_smalltbl_4_nf[];
+extern const struct cputbl op_smalltbl_4[];
/* 68000 slow but compatible. */
-extern const struct cputbl op_smalltbl_5_nf[];
+extern const struct cputbl op_smalltbl_5[];
#endif
-#ifdef WINUAE_ARANYM
-static void flush_icache_hard(int n);
-static void flush_icache_lazy(int n);
-static void flush_icache_none(int n);
-void (*flush_icache)(int n) = flush_icache_none;
-#endif
+static void flush_icache_hard(int);
+static void flush_icache_lazy(int);
+static void flush_icache_none(int);
+//void (*flush_icache)(int) = flush_icache_none;
static bigstate live;
static smallstate empty_ss;
static void setlock(int r);
static int readreg_specific(int r, int size, int spec);
static int writereg_specific(int r, int size, int spec);
-static void prepare_for_call_1(void);
-static void prepare_for_call_2(void);
-static void align_target(uae_u32 a);
-static void inline flush_cpu_icache(void *from, void *to);
static void inline write_jmp_target(uae_u32 *jmpaddr, cpuop_func* a);
-static void inline emit_jmp_target(uae_u32 a);
uae_u32 m68k_pc_offset;
#endif
#include "disasm-glue.h"
-#ifdef JIT_DEBUG
+bool disasm_this_inst;
+
+#if defined(JIT_DEBUG) || (defined(HAVE_DISASM_NATIVE) && defined(HAVE_DISASM_M68K))
static void disasm_block(int disasm_target, const uint8 *start, size_t length)
{
UNUSED(start);
disasm_info.memory_vma = ((memptr)((uintptr_t)(start) - MEMBaseDiff));
while (length > 0)
{
- int isize = m68k_disasm_to_buf(&disasm_info, buf);
+ int isize = m68k_disasm_to_buf(&disasm_info, buf, 1);
bug("%s", buf);
if (isize < 0)
break;
while (start < end)
{
- start = x86_disasm(start, buf);
+ start = x86_disasm(start, buf, 1);
bug("%s", buf);
}
}
while (start < end)
{
- start = arm_disasm(start, buf);
+ start = arm_disasm(start, buf, 1);
bug("%s", buf);
}
}
disasm_block(TARGET_M68K, start, length);
}
#endif
-#endif
+#endif /* WINUAE_ARANYM */
/*******************************************************************
static void prepare_block(blockinfo* bi);
-/* Management of blockinfos.
+/* Managment of blockinfos.
A blockinfo struct is allocated whenever a new block has to be
compiled. If the list of free blockinfos is empty, we allocate a new
static inline uae_u32 reverse32(uae_u32 v)
{
-#ifdef WINUAE_ARANYM
- // gb-- We have specialized byteswapping functions, just use them
return do_byteswap_32(v);
-#elif _MSC_VER
- return _byteswap_ulong(v);
-#else
- return ((v>>24)&0xff) | ((v>>8)&0xff00) | ((v<<8)&0xff0000) | ((v<<24)&0xff000000);
-#endif
}
void set_target(uae_u8* t)
static inline void do_load_reg(int n, int r)
{
if (r == FLAGTMP)
- raw_load_flagreg(n, r);
+ raw_load_flagreg(n);
else if (r == FLAGX)
- raw_load_flagx(n, r);
+ raw_load_flagx(n);
else
compemu_raw_mov_l_rm(n, (uintptr) live.state[r].mem);
}
evict(r);
}
+/* XXFIXME: val may be 64bit address for PC_P */
static inline void set_const(int r, uae_u32 val)
{
disassociate(r);
static void f_tomem(int r)
{
if (live.fate[r].status==DIRTY) {
- if (use_long_double) {
- raw_fmov_ext_mr((uintptr)live.fate[r].mem, live.fate[r].realreg);
- } else {
- raw_fmov_mr((uintptr)live.fate[r].mem, live.fate[r].realreg);
- }
+#if defined(USE_LONG_DOUBLE)
+ raw_fmov_ext_mr((uintptr)live.fate[r].mem,live.fate[r].realreg);
+#else
+ raw_fmov_mr((uintptr)live.fate[r].mem,live.fate[r].realreg);
+#endif
live.fate[r].status=CLEAN;
}
}
static void f_tomem_drop(int r)
{
if (live.fate[r].status==DIRTY) {
- if (use_long_double) {
- raw_fmov_ext_mr_drop((uintptr)live.fate[r].mem, live.fate[r].realreg);
- } else {
- raw_fmov_mr_drop((uintptr)live.fate[r].mem, live.fate[r].realreg);
- }
+#if defined(USE_LONG_DOUBLE)
+ raw_fmov_ext_mr_drop((uintptr)live.fate[r].mem,live.fate[r].realreg);
+#else
+ raw_fmov_mr_drop((uintptr)live.fate[r].mem,live.fate[r].realreg);
+#endif
live.fate[r].status=INMEM;
}
}
if (!willclobber) {
if (live.fate[r].status!=UNDEF) {
- if (use_long_double) {
- raw_fmov_ext_rm(bestreg, (uintptr)live.fate[r].mem);
- } else {
- raw_fmov_rm(bestreg, (uintptr)live.fate[r].mem);
- }
+#if defined(USE_LONG_DOUBLE)
+ raw_fmov_ext_rm(bestreg,(uintptr)live.fate[r].mem);
+#else
+ raw_fmov_rm(bestreg,(uintptr)live.fate[r].mem);
+#endif
}
live.fate[r].status=CLEAN;
}
return answer;
}
+/********************************************************************
+ * Support functions, internal *
+ ********************************************************************/
+
+
+static void align_target(uae_u32 a)
+{
+ if (!a)
+ return;
+
+ if (tune_nop_fillers)
+ raw_emit_nop_filler(a - (((uintptr)target) & (a - 1)));
+ else {
+ /* Fill with NOPs --- makes debugging with gdb easier */
+ while ((uintptr)target&(a-1))
+ emit_byte(0x90); // Attention x86 specific code
+ }
+}
+
+static inline int isinrom(uintptr addr)
+{
+#ifdef UAE
+ return (addr >= uae_p32(kickmem_bank.baseaddr) &&
+ addr < uae_p32(kickmem_bank.baseaddr + 8 * 65536));
+#else
+ return ((addr >= (uintptr)ROMBaseHost) && (addr < (uintptr)ROMBaseHost + ROMSize));
+#endif
+}
+
+#if defined(UAE) || defined(FLIGHT_RECORDER)
+static void flush_all(void)
+{
+ int i;
+
+ log_flush();
+ for (i=0;i<VREGS;i++)
+ if (live.state[i].status==DIRTY) {
+ if (!call_saved[live.state[i].realreg]) {
+ tomem(i);
+ }
+ }
+ for (i=0;i<VFREGS;i++)
+ if (f_isinreg(i))
+ f_evict(i);
+ raw_fp_cleanup_drop();
+}
+
+/* Make sure all registers that will get clobbered by a call are
+ save and sound in memory */
+static void prepare_for_call_1(void)
+{
+ flush_all(); /* If there are registers that don't get clobbered,
+ * we should be a bit more selective here */
+}
+
+/* We will call a C routine in a moment. That will clobber all registers,
+ so we need to disassociate everything */
+static void prepare_for_call_2(void)
+{
+ int i;
+ for (i=0;i<N_REGS;i++)
+ if (!call_saved[i] && live.nat[i].nholds>0)
+ free_nreg(i);
+
+ for (i=0;i<N_FREGS;i++)
+ if (live.fat[i].nholds>0)
+ f_free_nreg(i);
+
+ live.flags_in_flags=TRASH; /* Note: We assume we already rescued the
+ flags at the very start of the call_r
+ functions! */
+}
+#endif
+
#if defined(CPU_arm)
#include "compemu_midfunc_arm.cpp"
}
}
+/* for building exception frames */
+void compemu_exc_make_frame(int format, int sr, int ret, int nr, int tmp)
+{
+ lea_l_brr(SP_REG, SP_REG, -2);
+ mov_l_ri(tmp, (format << 12) + (nr * 4)); /* format | vector */
+ writeword(SP_REG, tmp, tmp);
+
+ lea_l_brr(SP_REG, SP_REG, -4);
+ writelong(SP_REG, ret, tmp);
+
+ lea_l_brr(SP_REG, SP_REG, -2);
+ writeword_clobber(SP_REG, sr, tmp);
+ remove_offset(SP_REG, -1);
+ if (isinreg(SP_REG))
+ evict(SP_REG);
+ else
+ flush_reg(SP_REG);
+}
+
+void compemu_make_sr(int sr, int tmp)
+{
+ flush_flags(); /* low level */
+ flush_reg(FLAGX);
+
+#if defined (OPTIMIZED_FLAGS) || defined(UAE)
+
+ /*
+ * x86 EFLAGS: (!SAHF_SETO_PROFITABLE)
+ * FEDCBA98 76543210
+ * ----V--- NZ-----C
+ *
+ * <--AH--> <--AL--> (SAHF_SETO_PROFITABLE)
+ * FEDCBA98 76543210
+ * NZxxxxxC xxxxxxxV
+ *
+ * arm RFLAGS:
+ * FEDCBA98 76543210 FEDCBA98 76543210
+ * NZCV---- -------- -------- --------
+ *
+ * -> m68k SR:
+ * --S--III ---XNZVC
+ *
+ * Master-Bit and traceflags are ignored here,
+ * since they are not emulated in JIT code
+ */
+ mov_l_rm(sr, uae_p32(live.state[FLAGTMP].mem));
+ mov_l_ri(tmp, FLAGVAL_N|FLAGVAL_Z|FLAGVAL_V|FLAGVAL_C);
+ and_l(sr, tmp);
+ mov_l_rr(tmp, sr);
+
+#if (defined(CPU_i386) && defined(X86_ASSEMBLY)) || (defined(CPU_x86_64) && defined(X86_64_ASSEMBLY))
+#ifndef SAHF_SETO_PROFITABLE
+ ror_b_ri(sr, FLAGBIT_N - 3); /* move NZ into position; C->4 */
+ shrl_w_ri(tmp, FLAGBIT_V - 1); /* move V into position in tmp */
+ or_l(sr, tmp); /* or V flag to SR */
+ mov_l_rr(tmp, sr);
+ shrl_b_ri(tmp, (8 - (FLAGBIT_N - 3)) - FLAGBIT_C); /* move C into position in tmp */
+ or_l(sr, tmp); /* or C flag to SR */
+#else
+ ror_w_ri(sr, FLAGBIT_N - 3); /* move NZ in position; V->4, C->12 */
+ shrl_w_ri(tmp, (16 - (FLAGBIT_N - 3)) - FLAGBIT_V - 1); /* move V into position in tmp; C->9 */
+ or_l(sr, tmp); /* or V flag to SR */
+ shrl_w_ri(tmp, FLAGBIT_C + FLAGBIT_V - 1); /* move C into position in tmp */
+ or_l(sr, tmp); /* or C flag to SR */
+#endif
+ mov_l_ri(tmp, 0x0f);
+ and_l(sr, tmp);
+
+ mov_b_rm(tmp, uae_p32(®flags.x));
+ and_l_ri(tmp, FLAGVAL_X);
+ shll_l_ri(tmp, 4);
+ or_l(sr, tmp);
+
+#elif defined(CPU_arm) && defined(ARM_ASSEMBLY)
+ shrl_l_ri(sr, FLAGBIT_N - 3); /* move NZ into position */
+ ror_l_ri(tmp, FLAGBIT_C - 1); /* move C into position in tmp; V->31 */
+ and_l_ri(sr, 0xc);
+ or_l(sr, tmp); /* or C flag to SR */
+ shrl_l_ri(tmp, 31); /* move V into position in tmp */
+ or_l(sr, tmp); /* or V flag to SR */
+
+ mov_b_rm(tmp, uae_p32(®flags.x));
+ and_l_ri(tmp, FLAGVAL_X);
+ shrl_l_ri(tmp, FLAGBIT_X - 4);
+ or_l(sr, tmp);
+
+#else
+#error "unknown CPU"
+#endif
+
+#else
+
+ xor_l(sr, sr);
+ xor_l(tmp, tmp);
+ mov_b_rm(tmp, uae_p32(®s.c));
+ shll_l_ri(tmp, 0);
+ or_l(sr, tmp);
+ mov_b_rm(tmp, uae_p32(®s.v));
+ shll_l_ri(tmp, 1);
+ or_l(sr, tmp);
+ mov_b_rm(tmp, uae_p32(®s.z));
+ shll_l_ri(tmp, 2);
+ or_l(sr, tmp);
+ mov_b_rm(tmp, uae_p32(®s.n));
+ shll_l_ri(tmp, 3);
+ or_l(sr, tmp);
+
+#endif /* OPTIMIZED_FLAGS */
+
+ mov_b_rm(tmp, uae_p32(®s.s));
+ shll_l_ri(tmp, 13);
+ or_l(sr, tmp);
+ mov_l_rm(tmp, uae_p32(®s.intmask));
+ shll_l_ri(tmp, 8);
+ or_l(sr, tmp);
+ and_l_ri(sr, 0x271f);
+ mov_w_mr(uae_p32(®s.sr), sr);
+}
+
+void compemu_enter_super(int sr)
+{
+#if 0
+ fprintf(stderr, "enter_super: isinreg=%d rr=%d nholds=%d\n", isinreg(SP_REG), live.state[SP_REG].realreg, isinreg(SP_REG) ? live.nat[live.state[SP_REG].realreg].nholds : -1);
+#endif
+ remove_offset(SP_REG, -1);
+ if (isinreg(SP_REG))
+ evict(SP_REG);
+ else
+ flush_reg(SP_REG);
+ /*
+ * equivalent to:
+ * if (!regs.s)
+ * {
+ * regs.usp = m68k_areg(regs, 7);
+ * m68k_areg(regs, 7) = regs.isp;
+ * regs.s = 1;
+ * mmu_set_super(1);
+ * }
+ */
+ test_l_ri(sr, 0x2000);
+#if defined(CPU_i386) || defined(CPU_x86_64)
+ compemu_raw_jnz_b_oponly();
+ uae_u8 *branchadd = get_target();
+ skip_byte();
+#elif defined(CPU_arm)
+ compemu_raw_jnz_b_oponly();
+ uae_u8 *branchadd = get_target();
+ skip_byte();
+#endif
+ mov_l_mr((uintptr)®s.usp, SP_REG);
+ mov_l_rm(SP_REG, uae_p32(®s.isp));
+ mov_b_mi(uae_p32(®s.s), 1);
+#if defined(CPU_i386) || defined(CPU_x86_64)
+ *branchadd = get_target() - (branchadd + 1);
+#elif defined(CPU_arm)
+ *((uae_u32 *)branchadd - 3) = get_target() - (branchadd + 1);
+#endif
+}
+
/********************************************************************
* Scratch registers management *
********************************************************************/
return b ? "on" : "off";
}
-#ifdef UAE
-static
-#endif
void compiler_init(void)
{
static bool initialized = false;
if (initialized)
return;
+ flush_icache = flush_icache_none;
+
#ifdef UAE
+ flush_icache = lazy_flush ? flush_icache_lazy : flush_icache_hard;
#else
-#ifdef JIT_DEBUG
- // JIT debug mode ?
- JITDebug = bx_options.jit.jitdebug;
-#endif
jit_log("<JIT compiler> : enable runtime disassemblers : %s", JITDebug ? "yes" : "no");
-#ifdef USE_JIT_FPU
- // Use JIT compiler for FPU instructions ?
- avoid_fpu = !bx_options.jit.jitfpu;
-#else
- // JIT FPU is always disabled
- avoid_fpu = true;
-#endif
jit_log("<JIT compiler> : compile FPU instructions : %s", !avoid_fpu ? "yes" : "no");
// Get size of the translation cache (in KB)
jit_log("<JIT compiler> : separate blockinfo allocation : %s", str_on_off(USE_SEPARATE_BIA));
// Build compiler tables
+ init_table68k();
build_comp();
#endif
#endif
}
-#ifdef UAE
-static
-#endif
void compiler_exit(void)
{
#ifdef PROFILE_COMPILE_TIME
#else
#if DEBUG
#if defined(USE_DATA_BUFFER)
- jit_log("data_wasted = %d bytes", data_wasted);
+ jit_log("data_wasted = %ld bytes", data_wasted);
#endif
#endif
100.0*double(cum_reg_count)/double(tot_reg_count));
}
#endif
-}
-#ifdef UAE
-#else
-bool compiler_use_jit(void)
-{
- // Check for the "jit" prefs item
- if (!bx_options.jit.jit)
- return false;
-
- // Don't use JIT if translation cache size is less then MIN_CACHE_SIZE KB
- if (bx_options.jit.jitcachesize < MIN_CACHE_SIZE) {
- panicbug("<JIT compiler> : translation cache size is less than %d KB. Disabling JIT.\n", MIN_CACHE_SIZE);
- return false;
- }
-
- return true;
+ exit_table68k();
}
-#endif
-void init_comp(void)
+static void init_comp(void)
{
int i;
uae_s8* cb=can_byte;
}
else if (i==FP_RESULT) {
#ifdef UAE
- live.fate[i].mem=(uae_u32*)(®s.fp_result.fp);
+ live.fate[i].mem=(uae_u32*)(®s.fp_result);
#else
live.fate[i].mem=(uae_u32*)(&fpu.result);
#endif
raw_fp_init();
}
+void flush_reg(int reg)
+{
+ if (live.state[reg].needflush==NF_TOMEM)
+ {
+ switch (live.state[reg].status)
+ {
+ case INMEM:
+ if (live.state[reg].val)
+ {
+ compemu_raw_add_l_mi((uintptr)live.state[reg].mem, live.state[reg].val);
+ log_vwrite(reg);
+ live.state[reg].val = 0;
+ }
+ break;
+ case CLEAN:
+ case DIRTY:
+ remove_offset(reg, -1);
+ tomem(reg);
+ break;
+ case ISCONST:
+ if (reg != PC_P)
+ writeback_const(reg);
+ break;
+ default:
+ break;
+ }
+ Dif (live.state[reg].val && reg!=PC_P)
+ {
+ jit_log("Register %d still has val %x", reg, live.state[reg].val);
+ }
+ }
+}
+
/* Only do this if you really mean it! The next call should be to init!*/
void flush(int save_regs)
{
}
}
for (i=0;i<VREGS;i++) {
- if (live.state[i].needflush==NF_TOMEM) {
- switch(live.state[i].status) {
- case INMEM:
- if (live.state[i].val) {
- compemu_raw_add_l_mi((uintptr)live.state[i].mem,live.state[i].val);
- log_vwrite(i);
- live.state[i].val=0;
- }
- break;
- case CLEAN:
- case DIRTY:
- remove_offset(i,-1);
- tomem(i);
- break;
- case ISCONST:
- if (i!=PC_P)
- writeback_const(i);
- break;
- default: break;
- }
- Dif (live.state[i].val && i!=PC_P) {
- jit_log("Register %d still has val %x", i,live.state[i].val);
- }
- }
+ flush_reg(i);
}
for (i=0;i<VFREGS;i++) {
if (live.fate[i].needflush==NF_TOMEM &&
}
#endif
-void freescratch(void)
+static void freescratch(void)
{
int i;
for (i=0;i<N_REGS;i++)
}
}
-/********************************************************************
- * Support functions, internal *
- ********************************************************************/
-
-
-static void align_target(uae_u32 a)
-{
- if (!a)
- return;
-
- if (tune_nop_fillers)
- raw_emit_nop_filler(a - (((uintptr)target) & (a - 1)));
- else {
- /* Fill with NOPs --- makes debugging with gdb easier */
- while ((uintptr)target&(a-1))
- emit_byte(0x90); // Attention x86 specific code
- }
-}
-
-static inline int isinrom(uintptr addr)
-{
-#ifdef UAE
- return (addr >= uae_p32(kickmem_bank.baseaddr) &&
- addr < uae_p32(kickmem_bank.baseaddr + 8 * 65536));
-#else
- return ((addr >= (uintptr)ROMBaseHost) && (addr < (uintptr)ROMBaseHost + ROMSize));
-#endif
-}
-
-static void flush_all(void)
-{
- int i;
-
- log_flush();
- for (i=0;i<VREGS;i++)
- if (live.state[i].status==DIRTY) {
- if (!call_saved[live.state[i].realreg]) {
- tomem(i);
- }
- }
- for (i=0;i<VFREGS;i++)
- if (f_isinreg(i))
- f_evict(i);
- raw_fp_cleanup_drop();
-}
-
-/* Make sure all registers that will get clobbered by a call are
- save and sound in memory */
-static void prepare_for_call_1(void)
-{
- flush_all(); /* If there are registers that don't get clobbered,
- * we should be a bit more selective here */
-}
-
-/* We will call a C routine in a moment. That will clobber all registers,
- so we need to disassociate everything */
-static void prepare_for_call_2(void)
-{
- int i;
- for (i=0;i<N_REGS;i++)
- if (!call_saved[i] && live.nat[i].nholds>0)
- free_nreg(i);
-
- for (i=0;i<N_FREGS;i++)
- if (live.fat[i].nholds>0)
- f_free_nreg(i);
-
- live.flags_in_flags=TRASH; /* Note: We assume we already rescued the
- flags at the very start of the call_r
- functions! */
-}
-
/********************************************************************
* Memory access and related functions, CREATE time *
********************************************************************/
#if FIXED_ADDRESSING
lea_l_brr(dest,address,MEMBaseDiff);
#else
-# error "Only fixed addressing mode supported"
+# error "Only fixed adressing mode supported"
#endif
forget_about(tmp);
(void) f;
void set_cache_state(int enabled)
{
if (enabled!=cache_enabled)
- flush_icache_hard(77);
+ flush_icache_hard(3);
cache_enabled=enabled;
}
void alloc_cache(void)
{
if (compiled_code) {
- flush_icache_hard(6);
+ flush_icache_hard(3);
vm_release(compiled_code, cache_size * 1024);
compiled_code = 0;
}
r=REG_PC_TMP;
compemu_raw_mov_l_rm(r, uae_p32(®s.pc_p));
compemu_raw_and_l_ri(r,TAGMASK);
+ {
+ //verify(sizeof(cache_tags[0]) == sizeof(void *));
+ }
compemu_raw_jmp_m_indexed(uae_p32(cache_tags), r, sizeof(void *));
/* now the exit points */
return opcode;
}
+
+#ifdef USE_JIT_FPU
+static struct {
+ const char *name;
+ bool *const disabled;
+} const jit_opcodes[] = {
+ { "fbcc", &jit_disable.fbcc },
+ { "fdbcc", &jit_disable.fdbcc },
+ { "fscc", &jit_disable.fscc },
+ { "ftrapcc", &jit_disable.ftrapcc },
+ { "fsave", &jit_disable.fsave },
+ { "frestore", &jit_disable.frestore },
+ { "fmove", &jit_disable.fmove },
+ { "fmovec", &jit_disable.fmovec },
+ { "fmovem", &jit_disable.fmovem },
+ { "fmovecr", &jit_disable.fmovecr },
+ { "fint", &jit_disable.fint },
+ { "fsinh", &jit_disable.fsinh },
+ { "fintrz", &jit_disable.fintrz },
+ { "fsqrt", &jit_disable.fsqrt },
+ { "flognp1", &jit_disable.flognp1 },
+ { "fetoxm1", &jit_disable.fetoxm1 },
+ { "ftanh", &jit_disable.ftanh },
+ { "fatan", &jit_disable.fatan },
+ { "fasin", &jit_disable.fasin },
+ { "fatanh", &jit_disable.fatanh },
+ { "fsin", &jit_disable.fsin },
+ { "ftan", &jit_disable.ftan },
+ { "fetox", &jit_disable.fetox },
+ { "ftwotox", &jit_disable.ftwotox },
+ { "ftentox", &jit_disable.ftentox },
+ { "flogn", &jit_disable.flogn },
+ { "flog10", &jit_disable.flog10 },
+ { "flog2", &jit_disable.flog2 },
+ { "fabs", &jit_disable.fabs },
+ { "fcosh", &jit_disable.fcosh },
+ { "fneg", &jit_disable.fneg },
+ { "facos", &jit_disable.facos },
+ { "fcos", &jit_disable.fcos },
+ { "fgetexp", &jit_disable.fgetexp },
+ { "fgetman", &jit_disable.fgetman },
+ { "fdiv", &jit_disable.fdiv },
+ { "fmod", &jit_disable.fmod },
+ { "fadd", &jit_disable.fadd },
+ { "fmul", &jit_disable.fmul },
+ { "fsgldiv", &jit_disable.fsgldiv },
+ { "frem", &jit_disable.frem },
+ { "fscale", &jit_disable.fscale },
+ { "fsglmul", &jit_disable.fsglmul },
+ { "fsub", &jit_disable.fsub },
+ { "fsincos", &jit_disable.fsincos },
+ { "fcmp", &jit_disable.fcmp },
+ { "ftst", &jit_disable.ftst },
+};
+
+static bool read_fpu_opcode(const char **pp)
+{
+ const char *p = *pp;
+ const char *end;
+ size_t len;
+ unsigned int i;
+
+ end = p;
+ while (*end != '\0' && *end != ',')
+ end++;
+ len = end - p;
+ if (*end != '\0')
+ end++;
+ for (i = 0; i < (sizeof(jit_opcodes) / sizeof(jit_opcodes[0])); i++)
+ {
+ if (len == strlen(jit_opcodes[i].name) && strnicmp(jit_opcodes[i].name, p, len) == 0)
+ {
+ *jit_opcodes[i].disabled = true;
+ jit_log("<JIT compiler> : disabled %s", jit_opcodes[i].name);
+ *pp = end;
+ return true;
+ }
+ }
+ return false;
+}
+#endif
+
static bool merge_blacklist()
{
#ifdef UAE
const char *blacklist = "";
#else
const char *blacklist = bx_options.jit.jitblacklist;
+#endif
+#ifdef USE_JIT_FPU
+ for (unsigned int i = 0; i < (sizeof(jit_opcodes) / sizeof(jit_opcodes[0])); i++)
+ *jit_opcodes[i].disabled = false;
#endif
if (blacklist[0] != '\0') {
const char *p = blacklist;
int opcode1 = read_opcode(p);
if (opcode1 < 0)
+ {
+#ifdef USE_JIT_FPU
+ if (read_fpu_opcode(&p))
+ continue;
+#endif
+ bug("<JIT compiler> : invalid opcode %s", p);
return false;
+ }
p += 4;
int opcode2 = opcode1;
p++;
opcode2 = read_opcode(p);
if (opcode2 < 0)
+ {
+ bug("<JIT compiler> : invalid opcode %s", p);
return false;
+ }
p += 4;
}
void build_comp(void)
{
+#ifdef FSUAE
+ if (!g_fs_uae_jit_compiler) {
+ jit_log("JIT: JIT compiler is not enabled");
+ return;
+ }
+#endif
int i;
unsigned long opcode;
const struct comptbl* tbl=op_smalltbl_0_comp_ff;
unsigned int cpu_level = 4; // 68040
const struct cputbl *nfctbl = op_smalltbl_0_nf;
#else
+ unsigned int cpu_level = (currprefs.cpu_model - 68000) / 10;
+ if (cpu_level > 4)
+ cpu_level--;
#ifdef NOFLAGS_SUPPORT
- struct comptbl *nfctbl = (currprefs.cpu_level >= 5 ? op_smalltbl_0_nf
- : currprefs.cpu_level == 4 ? op_smalltbl_1_nf
- : (currprefs.cpu_level == 2 || currprefs.cpu_level == 3) ? op_smalltbl_2_nf
- : currprefs.cpu_level == 1 ? op_smalltbl_3_nf
- : ! currprefs.cpu_compatible ? op_smalltbl_4_nf
- : op_smalltbl_5_nf);
+ extern const struct cputbl *uaegetjitcputbl(void);
+ const struct cputbl *nfctbl = uaegetjitcputbl();
#endif
#endif
// Initialize target CPU (check for features, e.g. CMOV, rat stalls)
#endif
prop[opcode].use_flags = FLAG_ALL;
prop[opcode].set_flags = FLAG_ALL;
-#ifdef UAE
- prop[opcode].is_jump=1;
-#else
prop[opcode].cflow = fl_trap; // ILLEGAL instructions do trap
-#endif
}
for (i = 0; tbl[i].opcode < 65536; i++) {
-#ifdef UAE
- int isjmp = (tbl[i].specific & COMP_OPCODE_ISJUMP);
- int isaddx = (tbl[i].specific & COMP_OPCODE_ISADDX);
- int iscjmp = (tbl[i].specific & COMP_OPCODE_ISCJUMP);
-
- prop[cft_map(tbl[i].opcode)].is_jump = isjmp;
- prop[cft_map(tbl[i].opcode)].is_const_jump = iscjmp;
- prop[cft_map(tbl[i].opcode)].is_addx = isaddx;
-#else
int cflow = table68k[tbl[i].opcode].cflow;
if (follow_const_jumps && (tbl[i].specific & COMP_OPCODE_ISCJUMP))
cflow = fl_const_jump;
else
cflow &= ~fl_const_jump;
prop[cft_map(tbl[i].opcode)].cflow = cflow;
-#endif
bool uses_fpu = (tbl[i].specific & COMP_OPCODE_USES_FPU) != 0;
if (uses_fpu && avoid_fpu)
else
nfcompfunctbl[cft_map(nftbl[i].opcode)] = nftbl[i].handler;
#ifdef NOFLAGS_SUPPORT
- nfcpufunctbl[cft_map(nftbl[i].opcode)] = nfctbl[i].handler;
+ nfcpufunctbl[cft_map(nftbl[i].opcode)] = nfctbl[i].handler_nf;
#endif
}
#ifdef NOFLAGS_SUPPORT
- for (i = 0; nfctbl[i].handler; i++) {
- nfcpufunctbl[cft_map(nfctbl[i].opcode)] = nfctbl[i].handler;
+ for (i = 0; nfctbl[i].handler_nf; i++) {
+ nfcpufunctbl[cft_map(nfctbl[i].opcode)] = nfctbl[i].handler_nf;
}
#endif
cpuop_func *nfcf;
#endif
int isaddx;
-#ifdef UAE
- int isjmp,iscjmp;
-#else
int cflow;
-#endif
-#ifdef UAE
- int cpu_level = (currprefs.cpu_model - 68000) / 10;
- if (cpu_level > 4)
- cpu_level--;
-#endif
if ((instrmnem)table68k[opcode].mnemo == i_ILLG || table68k[opcode].clev > cpu_level)
continue;
#endif
isaddx = prop[cft_map(table68k[opcode].handler)].is_addx;
prop[cft_map(opcode)].is_addx = isaddx;
-#ifdef UAE
- isjmp = prop[cft_map(table68k[opcode].handler)].is_jump;
- iscjmp = prop[cft_map(table68k[opcode].handler)].is_const_jump;
- prop[cft_map(opcode)].is_jump = isjmp;
- prop[cft_map(opcode)].is_const_jump = iscjmp;
-#else
cflow = prop[cft_map(table68k[opcode].handler)].cflow;
prop[cft_map(opcode)].cflow = cflow;
-#endif
compfunctbl[cft_map(opcode)] = f;
nfcompfunctbl[cft_map(opcode)] = nff;
#ifdef NOFLAGS_SUPPORT
prop[cft_map(opcode)].use_flags = table68k[opcode].flaglive;
/* Unconditional jumps don't evaluate condition codes, so they
* don't actually use any flags themselves */
-#ifdef UAE
- if (prop[cft_map(opcode)].is_const_jump)
-#else
if (prop[cft_map(opcode)].cflow & fl_const_jump)
-#endif
prop[cft_map(opcode)].use_flags = 0;
}
#ifdef NOFLAGS_SUPPORT
- for (i = 0; nfctbl[i].handler != NULL; i++) {
+ for (i = 0; nfctbl[i].handler_nf != NULL; i++) {
if (nfctbl[i].specific)
- nfcpufunctbl[cft_map(tbl[i].opcode)] = nfctbl[i].handler;
+ nfcpufunctbl[cft_map(tbl[i].opcode)] = nfctbl[i].handler_nf;
}
#endif
{
jit_log("<JIT compiler> : blacklist merge failure!");
}
-
+
count=0;
for (opcode = 0; opcode < 65536; opcode++) {
if (compfunctbl[cft_map(opcode)])
}
-static void flush_icache_none(int)
+static void flush_icache_none(int v)
{
/* Nothing to do. */
}
-void flush_icache_hard(int n)
+void flush_icache_hard(int v)
{
blockinfo* bi, *dbi;
jit_log("JIT: Flush Icache_hard(%d/%x/%p), %u KB",
n,regs.pc,regs.pc_p,current_cache_size/1024);
#endif
- UNUSED(n);
bi=active;
while(bi) {
cache_tags[cacheline(bi->pc_p)].handler=(cpuop_func*)popall_execute_normal;
we simply mark everything as "needs to be checked".
*/
-#ifdef WINUAE_ARANYM
-static inline void flush_icache_lazy(int)
-#else
-void flush_icache(int n)
-#endif
+static inline void flush_icache_lazy(int v)
{
blockinfo* bi;
blockinfo* bi2;
-#ifdef UAE
- if (currprefs.comp_hardflush) {
- flush_icache_hard(n);
- return;
- }
-#endif
if (!active)
return;
active=NULL;
}
-#ifdef UAE
-static
-#endif
-void flush_icache_range(uae_u32 start, uae_u32 length)
+
+#if 0
+static void flush_icache_range(uae_u32 start, uae_u32 length)
{
if (!active)
return;
UNUSED(start);
UNUSED(length);
#endif
- flush_icache(-1);
+ flush_icache();
}
+#endif
-/*
-static void catastrophe(void)
-{
- jit_abort("catastprophe");
-}
-*/
int failure;
#ifdef UAE
+#if defined(HAVE_GET_WORD_UNSWAPPED)
+#define DO_GET_OPCODE(a) (do_get_mem_word_unswapped((uae_u16*)(a)))
+#else
static inline unsigned int get_opcode_cft_map(unsigned int f)
{
- return ((f >> 8) & 255) | ((f & 255) << 8);
+ return do_byteswap_16(f);
}
#define DO_GET_OPCODE(a) (get_opcode_cft_map((uae_u16)*(a)))
+#endif
#else
#if defined(HAVE_GET_WORD_UNSWAPPED) && !defined(FULLMMU)
# define DO_GET_OPCODE(a) (do_get_mem_word_unswapped((uae_u16 *)(a)))
jit_log(" ");
jit_log("### M68k processor state");
-#ifdef UAE
- m68k_dumpstate(NULL);
-#else
m68k_dumpstate(stderr, 0);
-#endif
jit_log(" ");
jit_log("### Block in Atari address space");
}
#endif
+
+#if 0 /* debugging helpers; activate as needed */
+static void print_exc_frame(uae_u32 opcode)
+{
+ int nr = (opcode & 0x0f) + 32;
+ if (nr != 0x45 && /* Timer-C */
+ nr != 0x1c && /* VBL */
+ nr != 0x46) /* ACIA */
+ {
+ memptr sp = m68k_areg(regs, 7);
+ uae_u16 sr = get_word(sp);
+ fprintf(stderr, "Exc:%02x SP: %08x USP: %08x SR: %04x PC: %08x Format: %04x", nr, sp, regs.usp, sr, get_long(sp + 2), get_word(sp + 6));
+ if (nr >= 32 && nr < 48)
+ {
+ fprintf(stderr, " Opcode: $%04x", sr & 0x2000 ? get_word(sp + 8) : get_word(regs.usp));
+ }
+ fprintf(stderr, "\n");
+ }
+}
+
+static void push_all_nat(void)
+{
+ raw_pushfl();
+ raw_push_l_r(EAX_INDEX);
+ raw_push_l_r(ECX_INDEX);
+ raw_push_l_r(EDX_INDEX);
+ raw_push_l_r(EBX_INDEX);
+ raw_push_l_r(EBP_INDEX);
+ raw_push_l_r(EDI_INDEX);
+ raw_push_l_r(ESI_INDEX);
+ raw_push_l_r(R8_INDEX);
+ raw_push_l_r(R9_INDEX);
+ raw_push_l_r(R10_INDEX);
+ raw_push_l_r(R11_INDEX);
+ raw_push_l_r(R12_INDEX);
+ raw_push_l_r(R13_INDEX);
+ raw_push_l_r(R14_INDEX);
+ raw_push_l_r(R15_INDEX);
+}
+
+static void pop_all_nat(void)
+{
+ raw_pop_l_r(R15_INDEX);
+ raw_pop_l_r(R14_INDEX);
+ raw_pop_l_r(R13_INDEX);
+ raw_pop_l_r(R12_INDEX);
+ raw_pop_l_r(R11_INDEX);
+ raw_pop_l_r(R10_INDEX);
+ raw_pop_l_r(R9_INDEX);
+ raw_pop_l_r(R8_INDEX);
+ raw_pop_l_r(ESI_INDEX);
+ raw_pop_l_r(EDI_INDEX);
+ raw_pop_l_r(EBP_INDEX);
+ raw_pop_l_r(EBX_INDEX);
+ raw_pop_l_r(EDX_INDEX);
+ raw_pop_l_r(ECX_INDEX);
+ raw_pop_l_r(EAX_INDEX);
+ raw_popfl();
+}
+#endif
+
+#if 0
+static void print_inst(void)
+{
+ disasm_m68k_block(regs.fault_pc + (uint8 *)MEMBaseDiff, 1);
+}
+#endif
+
+
#ifdef UAE
void compile_block(cpu_history *pc_hist, int blocklen, int totcycles)
{
redo_current_block=0;
if (current_compile_p >= MAX_COMPILE_PTR)
- flush_icache_hard(7);
+ flush_icache_hard(3);
alloc_blockinfos();
#ifdef USE_CPU_EMUL_SERVICES
compemu_raw_sub_l_mi((uintptr)&emulated_ticks,blocklen);
compemu_raw_jcc_b_oponly(NATIVE_CC_GT);
- uae_s8 *branchadd=(uae_s8*)get_target();
+ uae_u8 *branchadd=get_target();
skip_byte();
raw_dec_sp(STACK_SHADOW_SPACE);
compemu_raw_call((uintptr)cpu_do_check_ticks);
raw_inc_sp(STACK_SHADOW_SPACE);
- *branchadd=(uintptr)get_target()-((uintptr)branchadd+1);
+ *branchadd=get_target()-(branchadd+1);
#endif
#ifdef JIT_DEBUG
remove_all_offsets();
prepare_for_call_1();
prepare_for_call_2();
- raw_mov_l_ri(REG_PAR1, ((uintptr)(pc_hist[i].location)) - MEMBaseDiff);
- raw_mov_w_ri(REG_PAR2, opcode);
+ raw_mov_l_ri(REG_PAR1, (memptr)((uintptr)pc_hist[i].location - MEMBaseDiff));
+ raw_mov_w_ri(REG_PAR2, cft_map(opcode));
raw_dec_sp(STACK_SHADOW_SPACE);
compemu_raw_call((uintptr)m68k_record_step);
raw_inc_sp(STACK_SHADOW_SPACE);
init_comp();
}
was_comp=1;
-
+
+#if defined(HAVE_DISASM_NATIVE) && defined(HAVE_DISASM_M68K)
+/* debugging helpers; activate as needed */
+#if 1
+ disasm_this_inst = false;
+ const uae_u8 *start_m68k_thisinst = (const uae_u8 *)pc_hist[i].location;
+ uae_u8 *start_native_thisinst = get_target();
+#endif
+#endif
+
#ifdef WINUAE_ARANYM
bool isnop = do_get_mem_word(pc_hist[i].location) == 0x4e71 ||
((i + 1) < blocklen && do_get_mem_word(pc_hist[i+1].location) == 0x4e71);
flush(1);
was_comp=0;
#endif
-
#ifdef WINUAE_ARANYM
/*
* workaround for buserror handling: on a "nop", write registers back
nop();
was_comp=0;
}
+#endif
+#if defined(HAVE_DISASM_NATIVE) && defined(HAVE_DISASM_M68K)
+
+/* debugging helpers; activate as needed */
+#if 0
+ disasm_m68k_block(start_m68k_thisinst, 1);
+ push_all_nat();
+ compemu_raw_mov_l_mi(uae_p32(®s.fault_pc), (uintptr)start_m68k_thisinst - MEMBaseDiff);
+ raw_dec_sp(STACK_SHADOW_SPACE);
+ compemu_raw_call(uae_p32(print_instn));
+ raw_inc_sp(STACK_SHADOW_SPACE);
+ pop_all_nat();
+#endif
+
+ if (disasm_this_inst)
+ {
+ disasm_m68k_block(start_m68k_thisinst, 1);
+#if 1
+ disasm_native_block(start_native_thisinst, get_target() - start_native_thisinst);
+#endif
+
+#if 0
+ push_all_nat();
+
+ raw_dec_sp(STACK_SHADOW_SPACE);
+ compemu_raw_mov_l_ri(REG_PAR1, (uae_u32)cft_map(opcode));
+ compemu_raw_call((uintptr)print_exc_frame);
+ raw_inc_sp(STACK_SHADOW_SPACE);
+
+ pop_all_nat();
+#endif
+
+ if (failure)
+ {
+ bug("(discarded)");
+ target = start_native_thisinst;
+ }
+ }
#endif
}
#endif
if (i < blocklen - 1) {
- uae_s8* branchadd;
+ uae_u8* branchadd;
- /* if (SPCFLAGS_TEST(SPCFLAG_STOP)) popall_do_nothing() */
- compemu_raw_mov_l_rm(0,(uintptr)specflags);
+ /* if (SPCFLAGS_TEST(SPCFLAG_ALL)) popall_do_nothing() */
+ compemu_raw_mov_l_rm(0, (uintptr)specflags);
compemu_raw_test_l_rr(0,0);
#if defined(USE_DATA_BUFFER)
data_check_end(8, 64); // just a pessimistic guess...
#endif
compemu_raw_jz_b_oponly();
- branchadd=(uae_s8*)get_target();
+ branchadd=get_target();
skip_byte();
#ifdef UAE
raw_sub_l_mi(uae_p32(&countdown),scaled_cycles(totcycles));
#endif
compemu_raw_jmp((uintptr)popall_do_nothing);
- *branchadd=(uintptr)get_target()-(uintptr)branchadd-1;
+ *branchadd = get_target() - (branchadd + 1);
}
}
}
}
#endif
- current_cache_size += get_target() - (uae_u8 *)current_compile_p;
+ current_cache_size += get_target() - current_compile_p;
#ifdef JIT_DEBUG
bi->direct_handler_size = get_target() - (uae_u8 *)current_block_start_target;
/* We will flush soon, anyway, so let's do it now */
if (current_compile_p >= MAX_COMPILE_PTR)
- flush_icache_hard(7);
+ flush_icache_hard(3);
bi->status=BI_ACTIVE;
if (redo_current_block)
do_extra_cycles(totcycles);
#endif
}
+
+#ifdef USE_CPU_EMUL_SERVICES
+ /* Account for compilation time */
+ cpu_do_check_ticks();
+#endif
}
#ifdef UAE
for (;;) {
uae_u32 opcode = GET_OPCODE;
#ifdef FLIGHT_RECORDER
- m68k_record_step(m68k_getpc(), opcode);
+ m68k_record_step(m68k_getpc(), cft_map(opcode));
#endif
(*cpufunctbl[opcode])(opcode);
cpu_check_ticks();
pc_hist[blocklen++].location = (uae_u16 *)regs.pc_p;
uae_u32 opcode = GET_OPCODE;
#ifdef FLIGHT_RECORDER
- m68k_record_step(m68k_getpc(), opcode);
+ m68k_record_step(m68k_getpc(), cft_map(opcode));
#endif
(*cpufunctbl[opcode])(opcode);
cpu_check_ticks();
regs.fault_pc,
regs.mmu_fault_addr, get_long (regs.vbr + 4*prb),
regs.regs[15]);
- flush_icache(0);
+ flush_icache();
Exception(prb, 0);
goto setjmpagain;
}
*
* Adaptation for ARAnyM/ARM, copyright 2001-2014
* Milan Jurik, Jens Heitmann
- *
+ *
* Adaptation for Basilisk II and improvements, copyright 2000-2005
* Gwenole Beauchesne
*
#undef abort
#ifdef UAE
-/*
-#define DISABLE_I_OR_AND_EOR
-#define DISABLE_I_SUB
-#define DISABLE_I_SUBA
-#define DISABLE_I_SUBX
-#define DISABLE_I_ADD
-#define DISABLE_I_ADDA
-#define DISABLE_I_ADDX
-#define DISABLE_I_NEG
-#define DISABLE_I_NEGX
-#define DISABLE_I_CLR
-#define DISABLE_I_NOT
-#define DISABLE_I_TST
-#define DISABLE_I_BCHG_BCLR_BSET_BTST
-#define DISABLE_I_CMPM_CMP
-#define DISABLE_I_CMPA
-#define DISABLE_I_MOVE
-#define DISABLE_I_MOVEA
-#define DISABLE_I_SWAP
-#define DISABLE_I_EXG
-#define DISABLE_I_EXT
-#define DISABLE_I_MVEL
-#define DISABLE_I_MVMLE
-#define DISABLE_I_RTD
-#define DISABLE_I_LINK
-#define DISABLE_I_UNLK
-#define DISABLE_I_RTS
-#define DISABLE_I_JSR
-#define DISABLE_I_JMP
-#define DISABLE_I_BSR
-#define DISABLE_I_BCC
-#define DISABLE_I_LEA
-#define DISABLE_I_PEA
-#define DISABLE_I_DBCC
-#define DISABLE_I_SCC
-#define DISABLE_I_MULU
-#define DISABLE_I_MULS
-#define DISABLE_I_ASR
-#define DISABLE_I_ASL
-#define DISABLE_I_LSR
-#define DISABLE_I_LSL
-#define DISABLE_I_ROL
-#define DISABLE_I_ROR
-#define DISABLE_I_MULL
-#define DISABLE_I_FPP
-#define DISABLE_I_FBCC
-#define DISABLE_I_FSCC
-#define DISABLE_I_MOVE16
-*/
+ /*
+ #define DISABLE_I_OR_AND_EOR
+ #define DISABLE_I_SUB
+ #define DISABLE_I_SUBA
+ #define DISABLE_I_SUBX
+ #define DISABLE_I_ADD
+ #define DISABLE_I_ADDA
+ #define DISABLE_I_ADDX
+ #define DISABLE_I_NEG
+ #define DISABLE_I_NEGX
+ #define DISABLE_I_CLR
+ #define DISABLE_I_NOT
+ #define DISABLE_I_TST
+ #define DISABLE_I_BCHG_BCLR_BSET_BTST
+ #define DISABLE_I_CMPM_CMP
+ #define DISABLE_I_CMPA
+ #define DISABLE_I_MOVE
+ #define DISABLE_I_MOVEA
+ #define DISABLE_I_SWAP
+ #define DISABLE_I_EXG
+ #define DISABLE_I_EXT
+ #define DISABLE_I_MVEL
+ #define DISABLE_I_MVMLE
+ #define DISABLE_I_RTD
+ #define DISABLE_I_LINK
+ #define DISABLE_I_UNLK
+ #define DISABLE_I_RTS
+ #define DISABLE_I_JSR
+ #define DISABLE_I_JMP
+ #define DISABLE_I_BSR
+ #define DISABLE_I_BCC
+ #define DISABLE_I_LEA
+ #define DISABLE_I_PEA
+ #define DISABLE_I_DBCC
+ #define DISABLE_I_SCC
+ #define DISABLE_I_MULU
+ #define DISABLE_I_MULS
+ #define DISABLE_I_ASR
+ #define DISABLE_I_ASL
+ #define DISABLE_I_LSR
+ #define DISABLE_I_LSL
+ #define DISABLE_I_ROL
+ #define DISABLE_I_ROR
+ #define DISABLE_I_MULL
+ #define DISABLE_I_FPP
+ #define DISABLE_I_FBCC
+ #define DISABLE_I_FSCC
+ #define DISABLE_I_MOVE16
+ */
+
#endif /* UAE */
#ifdef UAE
#define JIT_PATH "jit/"
+#ifdef FSUAE
+#define GEN_PATH "gen/"
+#else
#define GEN_PATH "jit/"
+#endif
#define RETURN "return 0;"
#define RETTYPE "uae_u32"
#define NEXT_CPU_LEVEL 5
#define RETURN "return;"
#define RETTYPE "void"
#define NEXT_CPU_LEVEL 4
-#define ua(s) s
#endif
#define BOOL_TYPE "int"
#define failure global_failure=1
#define FAILURE global_failure=1
#define isjump global_isjump=1
-#define is_const_jump global_iscjump=1;
+#define is_const_jump global_iscjump=1
#define isaddx global_isaddx=1
#define uses_cmov global_cmov=1
#define mayfail global_mayfail=1
static char endstr[1000];
static char lines[100000];
-static int comp_index=0;
#include "flags_x86.h"
-static int cond_codes[]={-1,-1,
- NATIVE_CC_HI,NATIVE_CC_LS,
- NATIVE_CC_CC,NATIVE_CC_CS,
- NATIVE_CC_NE,NATIVE_CC_EQ,
- -1,-1,
- NATIVE_CC_PL,NATIVE_CC_MI,
- NATIVE_CC_GE,NATIVE_CC_LT,
- NATIVE_CC_GT,NATIVE_CC_LE
- };
-
-static void comprintf(const char* format, ...)
+#ifndef __attribute__
+# ifndef __GNUC__
+# define __attribute__(x)
+# endif
+#endif
+
+#define GENA_GETV_NO_FETCH 0
+#define GENA_GETV_FETCH 1
+#define GENA_GETV_FETCH_ALIGN 2
+#define GENA_MOVEM_DO_INC 0
+#define GENA_MOVEM_NO_INC 1
+#define GENA_MOVEM_MOVE16 2
+
+
+static int cond_codes[] = { -1, -1,
+NATIVE_CC_HI, NATIVE_CC_LS,
+NATIVE_CC_CC, NATIVE_CC_CS,
+NATIVE_CC_NE, NATIVE_CC_EQ,
+-1, -1,
+NATIVE_CC_PL, NATIVE_CC_MI,
+NATIVE_CC_GE, NATIVE_CC_LT,
+NATIVE_CC_GT, NATIVE_CC_LE
+};
+
+static int brace_level;
+
+static char outbuffer[30000];
+
+static void comprintf(const char *format, ...)
{
- va_list args;
+ char outbuf[1000];
+ va_list parms;
+ va_start(parms, format);
+ _vsnprintf(outbuf, sizeof(outbuf) - 1, format, parms);
+ outbuf[sizeof(outbuf) - 1] = 0;
+ va_end(parms);
+
+ char *p = outbuf;
+ bool firstspace = true;
+ while (*p) {
+ char v = *p;
+ if (v == '\t' || (v == ' ' && p[1] == ' ') || (firstspace && v == ' ')) {
+ memmove(p, p + 1, strlen(p + 1) + 1);
+ } else {
+ firstspace = false;
+ p++;
+ }
+ }
+
+ p = outbuf;
+ for (;;) {
+ char *pe = p;
+ int islf = 0;
+ while (*pe != 0 && *pe != '\n') {
+ pe++;
+ }
+ if (*pe == '\n') {
+ islf = 1;
+ *pe = 0;
+ }
+
+ char outbuf2[1000];
+ strcpy(outbuf2, p);
+ outbuf2[pe - p] = 0;
+
+ if (outbuf2[0]) {
+ char *ps = outbuf2;
+ while (*ps) {
+ char v = *ps;
+ if (v == '}') {
+ brace_level--;
+ }
+ ps++;
+ }
+ for (int i = 0; i < brace_level; i++) {
+ strcat(outbuffer, "\t");
+ }
+ strcat(outbuffer, outbuf2);
+
+ ps = outbuf2;
+ while (*ps) {
+ char v = *ps;
+ if (v == '{') {
+ brace_level++;
+ }
+ ps++;
+ }
+ }
- va_start(args,format);
- comp_index+=vsprintf(lines+comp_index,format,args);
+ if (islf) {
+ strcat(outbuffer, "\n");
+ pe++;
+ }
+ if (*pe == 0)
+ break;
+ p = pe;
+ }
}
static void com_discard(void)
{
- comp_index=0;
+ outbuffer[0] = 0;
}
static void com_flush(void)
{
- int i;
- for (i=0;i<comp_index;i++)
- putchar(lines[i]);
- com_discard();
+ printf("%s", outbuffer);
+ com_discard();
}
static int *opcode_last_postfix;
static unsigned long *counts;
-static void
-read_counts (void)
+static void read_counts(void)
{
- FILE *file;
- unsigned long opcode, count, total;
- char name[20];
- int nr = 0;
- memset (counts, 0, 65536 * sizeof *counts);
-
- file = fopen ("frequent.68k", "r");
- if (file)
- {
- if (fscanf (file, "Total: %lu\n", &total) != 1) {
- assert(0);
- }
- while (fscanf (file, "%lx: %lu %s\n", &opcode, &count, name) == 3)
+ FILE *file;
+ unsigned long opcode, count, total;
+ char name[20];
+ int nr = 0;
+ memset(counts, 0, 65536 * sizeof * counts);
+
+ file = fopen("frequent.68k", "r");
+ if (file)
{
- opcode_next_clev[nr] = NEXT_CPU_LEVEL;
- opcode_last_postfix[nr] = -1;
- opcode_map[nr++] = opcode;
- counts[opcode] = count;
+ if (fscanf(file, "Total: %lu\n", &total) != 1) {
+ assert(0);
+ }
+ while (fscanf(file, "%lx: %lu %s\n", &opcode, &count, name) == 3)
+ {
+ opcode_next_clev[nr] = NEXT_CPU_LEVEL;
+ opcode_last_postfix[nr] = -1;
+ opcode_map[nr++] = opcode;
+ counts[opcode] = count;
+ }
+ fclose(file);
}
- fclose (file);
- }
- if (nr == nr_cpuop_funcs)
- return;
- for (opcode = 0; opcode < 0x10000; opcode++)
- {
- if (table68k[opcode].handler == -1 && table68k[opcode].mnemo != i_ILLG
- && counts[opcode] == 0)
+ if (nr == nr_cpuop_funcs)
+ return;
+ for (opcode = 0; opcode < 0x10000; opcode++)
{
- opcode_next_clev[nr] = NEXT_CPU_LEVEL;
- opcode_last_postfix[nr] = -1;
- opcode_map[nr++] = opcode;
- counts[opcode] = count;
+ if (table68k[opcode].handler == -1 && table68k[opcode].mnemo != i_ILLG
+ && counts[opcode] == 0)
+ {
+ opcode_next_clev[nr] = NEXT_CPU_LEVEL;
+ opcode_last_postfix[nr] = -1;
+ opcode_map[nr++] = opcode;
+ counts[opcode] = count;
+ }
}
- }
- assert (nr == nr_cpuop_funcs);
+ assert(nr == nr_cpuop_funcs);
}
static int n_braces = 0;
static int insn_n_cycles;
-static void
-start_brace (void)
+static void start_brace(void)
{
- n_braces++;
- comprintf ("{");
+ n_braces++;
+ comprintf("{\n");
}
-static void
-close_brace (void)
+static void close_brace(void)
{
- assert (n_braces > 0);
- n_braces--;
- comprintf ("}");
+ assert(n_braces > 0);
+ n_braces--;
+ comprintf("}\n");
}
-static void
-finish_braces (void)
+static void finish_braces(void)
{
- while (n_braces > 0)
- close_brace ();
+ while (n_braces > 0)
+ close_brace();
}
static inline void gen_update_next_handler(void)
{
- return; /* Can anything clever be done here? */
+ return; /* Can anything clever be done here? */
}
-static void gen_writebyte (const char* address, const char* source)
+static void gen_writebyte(const char *address, const char *source)
{
- comprintf("\twritebyte(%s,%s,scratchie);\n",address,source);
+ comprintf("\twritebyte(%s, %s, scratchie);\n", address, source);
}
-static void gen_writeword (const char* address, const char* source)
+static void gen_writeword(const char *address, const char *source)
{
- comprintf("\twriteword(%s,%s,scratchie);\n",address,source);
+ comprintf("\twriteword(%s, %s, scratchie);\n", address, source);
}
-static void gen_writelong (const char* address, const char* source)
+static void gen_writelong(const char *address, const char *source)
{
- comprintf("\twritelong(%s,%s,scratchie);\n",address,source);
+ comprintf("\twritelong(%s, %s, scratchie);\n", address, source);
}
-static void gen_readbyte (const char* address, const char* dest)
+static void gen_readbyte(const char *address, const char *dest)
{
- comprintf("\treadbyte(%s,%s,scratchie);\n",address,dest);
+ comprintf("\treadbyte(%s, %s, scratchie);\n", address, dest);
}
-static void gen_readword (const char* address, const char* dest)
+static void gen_readword(const char *address, const char *dest)
{
- comprintf("\treadword(%s,%s,scratchie);\n",address,dest);
+ comprintf("\treadword(%s,%s,scratchie);\n", address, dest);
}
-static void gen_readlong (const char* address, const char* dest)
+static void gen_readlong(const char *address, const char *dest)
{
- comprintf("\treadlong(%s,%s,scratchie);\n",address,dest);
+ comprintf("\treadlong(%s, %s, scratchie);\n", address, dest);
}
static const char *
-gen_nextilong (void)
+gen_nextilong(void)
{
- static char buffer[80];
+ static char buffer[80];
- sprintf (buffer, "comp_get_ilong((m68k_pc_offset+=4)-4)");
- insn_n_cycles += 4;
+ sprintf(buffer, "comp_get_ilong((m68k_pc_offset+=4)-4)");
+ insn_n_cycles += 4;
- long_opcode=1;
- return buffer;
+ long_opcode = 1;
+ return buffer;
}
static const char *
-gen_nextiword (void)
+gen_nextiword(void)
{
- static char buffer[80];
+ static char buffer[80];
- sprintf (buffer, "comp_get_iword((m68k_pc_offset+=2)-2)");
- insn_n_cycles+=2;
+ sprintf(buffer, "comp_get_iword((m68k_pc_offset+=2)-2)");
+ insn_n_cycles += 2;
- long_opcode=1;
- return buffer;
+ long_opcode = 1;
+ return buffer;
}
static const char *
-gen_nextibyte (void)
+gen_nextibyte(void)
{
- static char buffer[80];
+ static char buffer[80];
- sprintf (buffer, "comp_get_ibyte((m68k_pc_offset+=2)-2)");
- insn_n_cycles += 2;
+ sprintf(buffer, "comp_get_ibyte((m68k_pc_offset+=2)-2)");
+ insn_n_cycles += 2;
- long_opcode=1;
- return buffer;
+ long_opcode = 1;
+ return buffer;
}
static void
-swap_opcode (void)
+swap_opcode(void)
{
#ifdef UAE
/* no-op */
#endif
}
-static void
-sync_m68k_pc (void)
+static void sync_m68k_pc(void)
+{
+ comprintf("if (m68k_pc_offset > SYNC_PC_OFFSET) {\n");
+ comprintf("sync_m68k_pc();\n");
+ comprintf("}\n");
+}
+
+
+static void gen_set_fault_pc(void)
+{
+ start_brace();
+ comprintf("\tsync_m68k_pc();\n");
+ comprintf("\tuae_u32 retadd=start_pc+((char *)comp_pc_p-(char *)start_pc_p)+m68k_pc_offset;\n");
+ comprintf("\tint ret=scratchie++;\n"
+ "\tmov_l_ri(ret,retadd);\n"
+ "\tmov_l_mr((uintptr)®s.fault_pc,ret);\n");
+}
+
+
+static void make_sr(void)
+{
+ start_brace();
+ comprintf("\tint sr = scratchie++;\n");
+ comprintf("\tint tmp = scratchie++;\n");
+ comprintf("\tcompemu_make_sr(sr, tmp);\n");
+}
+
+
+static void disasm_this_inst(void)
{
- comprintf("\t if (m68k_pc_offset > SYNC_PC_OFFSET) sync_m68k_pc();\n");
+ comprintf("\tdisasm_this_inst = true;\n");
}
/* getv == 1: fetch data; getv != 0: check for odd address. If movem != 0,
* the calling routine handles Apdi and Aipi modes.
* gb-- movem == 2 means the same thing but for a MOVE16 instruction */
-static void
-genamode (amodes mode, const char *reg, wordsizes size, const char *name, int getv, int movem)
+static void genamode(amodes mode, const char *reg, wordsizes size, const char *name, int getv, int movem)
{
- start_brace ();
- switch (mode)
- {
- case Dreg: /* Do we need to check dodgy here? */
- assert (!movem);
- if (getv == 1 || getv==2) {
- /* We generate the variable even for getv==2, so we can use
- it as a destination for MOVE */
- comprintf ("\tint %s=%s;\n",name,reg);
- }
- return;
-
- case Areg:
- assert (!movem);
- if (getv == 1 || getv==2) {
- /* see above */
- comprintf ("\tint %s=dodgy?scratchie++:%s+8;\n",name,reg);
- if (getv==1) {
- comprintf ("\tif (dodgy) \n");
- comprintf ("\t\tmov_l_rr(%s,%s+8);\n",name, reg);
- }
- }
- return;
-
- case Aind:
- comprintf ("\tint %sa=dodgy?scratchie++:%s+8;\n",name,reg);
- comprintf ("\tif (dodgy) \n");
- comprintf ("\t\tmov_l_rr(%sa,%s+8);\n",name, reg);
- break;
- case Aipi:
- comprintf ("\tint %sa=scratchie++;\n",name,reg);
- comprintf ("\tmov_l_rr(%sa,%s+8);\n",name, reg);
- break;
- case Apdi:
- switch (size)
+ start_brace();
+ switch (mode)
{
- case sz_byte:
- if (movem) {
- comprintf ("\tint %sa=dodgy?scratchie++:%s+8;\n",name,reg);
- comprintf ("\tif (dodgy) \n");
- comprintf("\tmov_l_rr(%sa,8+%s);\n",name,reg);
- }
- else {
- start_brace();
- comprintf ("\tint %sa=dodgy?scratchie++:%s+8;\n",name,reg);
- comprintf("\tlea_l_brr(%s+8,%s+8,(uae_s32)-areg_byteinc[%s]);\n",reg,reg,reg);
- comprintf ("\tif (dodgy) \n");
- comprintf("\tmov_l_rr(%sa,8+%s);\n",name,reg);
- }
- break;
- case sz_word:
- if (movem) {
- comprintf ("\tint %sa=dodgy?scratchie++:%s+8;\n",name,reg);
- comprintf ("\tif (dodgy) \n");
- comprintf("\tmov_l_rr(%sa,8+%s);\n",name,reg);
- }
- else {
- start_brace();
- comprintf ("\tint %sa=dodgy?scratchie++:%s+8;\n",name,reg);
- comprintf("\tlea_l_brr(%s+8,%s+8,-2);\n",reg,reg);
- comprintf ("\tif (dodgy) \n");
- comprintf("\tmov_l_rr(%sa,8+%s);\n",name,reg);
- }
- break;
- case sz_long:
- if (movem) {
- comprintf ("\tint %sa=dodgy?scratchie++:%s+8;\n",name,reg);
- comprintf ("\tif (dodgy) \n");
- comprintf("\tmov_l_rr(%sa,8+%s);\n",name,reg);
- }
- else {
- start_brace();
- comprintf ("\tint %sa=dodgy?scratchie++:%s+8;\n",name,reg);
- comprintf("\tlea_l_brr(%s+8,%s+8,-4);\n",reg,reg);
- comprintf ("\tif (dodgy) \n");
- comprintf("\tmov_l_rr(%sa,8+%s);\n",name,reg);
- }
- break;
- default:
- assert(0);
- }
- break;
- case Ad16:
- comprintf("\tint %sa=scratchie++;\n",name);
- comprintf("\tmov_l_rr(%sa,8+%s);\n",name,reg);
- comprintf("\tlea_l_brr(%sa,%sa,(uae_s32)(uae_s16)%s);\n",name,name,gen_nextiword());
- break;
- case Ad8r:
- comprintf("\tint %sa=scratchie++;\n",name);
- comprintf("\tcalc_disp_ea_020(%s+8,%s,%sa,scratchie);\n",
- reg,gen_nextiword(),name);
- break;
+ case Dreg: /* Do we need to check dodgy here? */
+ assert(movem == GENA_MOVEM_DO_INC);
+ if (getv == GENA_GETV_FETCH || getv == GENA_GETV_FETCH_ALIGN)
+ {
+ /* We generate the variable even for getv==2, so we can use
+ it as a destination for MOVE */
+ comprintf("\tint %s = %s;\n", name, reg);
+ }
+ return;
- case PC16:
- comprintf("\tint %sa=scratchie++;\n",name);
- comprintf("\tuae_u32 address=start_pc+((char *)comp_pc_p-(char *)start_pc_p)+m68k_pc_offset;\n");
- comprintf ("\tuae_s32 PC16off = (uae_s32)(uae_s16)%s;\n", gen_nextiword ());
- comprintf("\tmov_l_ri(%sa,address+PC16off);\n",name);
- break;
+ case Areg:
+ assert(movem == GENA_MOVEM_DO_INC);
+ if (getv == GENA_GETV_FETCH || getv == GENA_GETV_FETCH_ALIGN)
+ {
+ /* see above */
+ comprintf("\tint %s = dodgy ? scratchie++ : %s + 8;\n", name, reg);
+ if (getv == GENA_GETV_FETCH)
+ {
+ comprintf("\tif (dodgy) \n");
+ comprintf("\t\tmov_l_rr(%s, %s + 8);\n", name, reg);
+ }
+ }
+ return;
- case PC8r:
- comprintf("\tint pctmp=scratchie++;\n");
- comprintf("\tint %sa=scratchie++;\n",name);
- comprintf("\tuae_u32 address=start_pc+((char *)comp_pc_p-(char *)start_pc_p)+m68k_pc_offset;\n");
- start_brace();
- comprintf("\tmov_l_ri(pctmp,address);\n");
+ case Aind:
+ comprintf("\tint %sa = dodgy ? scratchie++ : %s + 8;\n", name, reg);
+ comprintf("\tif (dodgy)\n");
+ comprintf("\t\tmov_l_rr(%sa, %s + 8);\n", name, reg);
+ break;
+ case Aipi:
+ comprintf("\tint %sa = scratchie++;\n", name);
+ comprintf("\tmov_l_rr(%sa, %s + 8);\n", name, reg);
+ break;
+ case Apdi:
+ switch (size)
+ {
+ case sz_byte:
+ if (movem != GENA_MOVEM_DO_INC)
+ {
+ comprintf("\tint %sa = dodgy ? scratchie++ : %s + 8;\n", name, reg);
+ comprintf("\tif (dodgy)\n");
+ comprintf("\t\tmov_l_rr(%sa, 8 + %s);\n", name, reg);
+ } else
+ {
+ start_brace();
+ comprintf("\tint %sa = dodgy ? scratchie++ : %s + 8;\n", name, reg);
+ comprintf("\tlea_l_brr(%s + 8, %s + 8, (uae_s32)-areg_byteinc[%s]);\n", reg, reg, reg);
+ comprintf("\tif (dodgy)\n");
+ comprintf("\t\tmov_l_rr(%sa, 8 + %s);\n", name, reg);
+ }
+ break;
+ case sz_word:
+ if (movem != GENA_MOVEM_DO_INC)
+ {
+ comprintf("\tint %sa=dodgy?scratchie++:%s+8;\n", name, reg);
+ comprintf("\tif (dodgy) \n");
+ comprintf("\tmov_l_rr(%sa,8+%s);\n", name, reg);
+ } else
+ {
+ start_brace();
+ comprintf("\tint %sa = dodgy ? scratchie++ : %s + 8;\n", name, reg);
+ comprintf("\tlea_l_brr(%s + 8, %s + 8, -2);\n", reg, reg);
+ comprintf("\tif (dodgy)\n");
+ comprintf("\t\tmov_l_rr(%sa, 8 + %s);\n", name, reg);
+ }
+ break;
+ case sz_long:
+ if (movem != GENA_MOVEM_DO_INC)
+ {
+ comprintf("\tint %sa = dodgy ? scratchie++ : %s + 8;\n", name, reg);
+ comprintf("\tif (dodgy)\n");
+ comprintf("\t\tmov_l_rr(%sa, 8 + %s);\n", name, reg);
+ } else
+ {
+ start_brace();
+ comprintf("\tint %sa = dodgy ? scratchie++ : %s + 8;\n", name, reg);
+ comprintf("\tlea_l_brr(%s + 8, %s + 8, -4);\n", reg, reg);
+ comprintf("\tif (dodgy)\n");
+ comprintf("\t\tmov_l_rr(%sa, 8 + %s);\n", name, reg);
+ }
+ break;
+ default:
+ assert(0);
+ break;
+ }
+ break;
+ case Ad16:
+ comprintf("\tint %sa = scratchie++;\n", name);
+ comprintf("\tmov_l_rr(%sa, 8 + %s);\n", name, reg);
+ comprintf("\tlea_l_brr(%sa, %sa, (uae_s32)(uae_s16)%s);\n", name, name, gen_nextiword());
+ break;
+ case Ad8r:
+ comprintf("\tint %sa = scratchie++;\n", name);
+ comprintf("\tcalc_disp_ea_020(%s + 8, %s, %sa, scratchie);\n", reg, gen_nextiword(), name);
+ break;
- comprintf("\tcalc_disp_ea_020(pctmp,%s,%sa,scratchie);\n",
- gen_nextiword(),name);
- break;
- case absw:
- comprintf ("\tint %sa = scratchie++;\n",name);
- comprintf ("\tmov_l_ri(%sa,(uae_s32)(uae_s16)%s);\n", name, gen_nextiword ());
- break;
- case absl:
- comprintf ("\tint %sa = scratchie++;\n",name);
- comprintf ("\tmov_l_ri(%sa,%s); /* absl */\n", name, gen_nextilong ());
- break;
- case imm:
- assert (getv == 1);
- switch (size)
- {
- case sz_byte:
- comprintf ("\tint %s = scratchie++;\n",name);
- comprintf ("\tmov_l_ri(%s,(uae_s32)(uae_s8)%s);\n", name, gen_nextibyte ());
- break;
- case sz_word:
- comprintf ("\tint %s = scratchie++;\n",name);
- comprintf ("\tmov_l_ri(%s,(uae_s32)(uae_s16)%s);\n", name, gen_nextiword ());
- break;
- case sz_long:
- comprintf ("\tint %s = scratchie++;\n",name);
- comprintf ("\tmov_l_ri(%s,%s);\n", name, gen_nextilong ());
- break;
- default:
- assert(0);
+ case PC16:
+ comprintf("\tint %sa = scratchie++;\n", name);
+ comprintf("\tuae_u32 address = start_pc + ((char *)comp_pc_p - (char *)start_pc_p) + m68k_pc_offset;\n");
+ comprintf("\tuae_s32 PC16off = (uae_s32)(uae_s16)%s;\n", gen_nextiword());
+ comprintf("\tmov_l_ri(%sa, address + PC16off);\n", name);
+ break;
+
+ case PC8r:
+ comprintf("\tint pctmp = scratchie++;\n");
+ comprintf("\tint %sa = scratchie++;\n", name);
+ comprintf("\tuae_u32 address = start_pc + ((char *)comp_pc_p - (char *)start_pc_p) + m68k_pc_offset;\n");
+ start_brace();
+ comprintf("\tmov_l_ri(pctmp,address);\n");
+
+ comprintf("\tcalc_disp_ea_020(pctmp, %s, %sa, scratchie);\n", gen_nextiword(), name);
+ break;
+ case absw:
+ comprintf("\tint %sa = scratchie++;\n", name);
+ comprintf("\tmov_l_ri(%sa, (uae_s32)(uae_s16)%s);\n", name, gen_nextiword());
+ break;
+ case absl:
+ comprintf("\tint %sa = scratchie++;\n", name);
+ comprintf("\tmov_l_ri(%sa, %s); /* absl */\n", name, gen_nextilong());
+ break;
+ case imm:
+ assert(getv == GENA_GETV_FETCH);
+ switch (size)
+ {
+ case sz_byte:
+ comprintf("\tint %s = scratchie++;\n", name);
+ comprintf("\tmov_l_ri(%s, (uae_s32)(uae_s8)%s);\n", name, gen_nextibyte());
+ break;
+ case sz_word:
+ comprintf("\tint %s = scratchie++;\n", name);
+ comprintf("\tmov_l_ri(%s, (uae_s32)(uae_s16)%s);\n", name, gen_nextiword());
+ break;
+ case sz_long:
+ comprintf("\tint %s = scratchie++;\n", name);
+ comprintf("\tmov_l_ri(%s, %s);\n", name, gen_nextilong());
+ break;
+ default:
+ assert(0);
+ break;
+ }
+ return;
+ case imm0:
+ assert(getv == GENA_GETV_FETCH);
+ comprintf("\tint %s = scratchie++;\n", name);
+ comprintf("\tmov_l_ri(%s, (uae_s32)(uae_s8)%s);\n", name, gen_nextibyte());
+ return;
+ case imm1:
+ assert(getv == GENA_GETV_FETCH);
+ comprintf("\tint %s = scratchie++;\n", name);
+ comprintf("\tmov_l_ri(%s, (uae_s32)(uae_s16)%s);\n", name, gen_nextiword());
+ return;
+ case imm2:
+ assert(getv == GENA_GETV_FETCH);
+ comprintf("\tint %s = scratchie++;\n", name);
+ comprintf("\tmov_l_ri(%s, %s);\n", name, gen_nextilong());
+ return;
+ case immi:
+ assert(getv == GENA_GETV_FETCH);
+ comprintf("\tint %s = scratchie++;\n", name);
+ comprintf("\tmov_l_ri(%s, %s);\n", name, reg);
+ return;
+ default:
+ assert(0);
+ break;
}
- return;
- case imm0:
- assert (getv == 1);
- comprintf ("\tint %s = scratchie++;\n",name);
- comprintf ("\tmov_l_ri(%s,(uae_s32)(uae_s8)%s);\n", name, gen_nextibyte ());
- return;
- case imm1:
- assert (getv == 1);
- comprintf ("\tint %s = scratchie++;\n",name);
- comprintf ("\tmov_l_ri(%s,(uae_s32)(uae_s16)%s);\n", name, gen_nextiword ());
- return;
- case imm2:
- assert (getv == 1);
- comprintf ("\tint %s = scratchie++;\n",name);
- comprintf ("\tmov_l_ri(%s,%s);\n", name, gen_nextilong ());
- return;
- case immi:
- assert (getv == 1);
- comprintf ("\tint %s = scratchie++;\n",name);
- comprintf ("\tmov_l_ri(%s,%s);\n", name, reg);
- return;
- default:
- assert(0);
- }
-
- /* We get here for all non-reg non-immediate addressing modes to
- * actually fetch the value. */
- if (getv == 1)
- {
- char astring[80];
- sprintf(astring,"%sa",name);
- switch (size)
+
+ /* We get here for all non-reg non-immediate addressing modes to
+ * actually fetch the value. */
+ if (getv == GENA_GETV_FETCH)
{
- case sz_byte:
- insn_n_cycles += 2;
- break;
- case sz_word:
- insn_n_cycles += 2;
- break;
- case sz_long:
- insn_n_cycles += 4;
- break;
- default:
- assert(0);
+ char astring[80];
+ sprintf(astring, "%sa", name);
+ switch (size)
+ {
+ case sz_byte:
+ insn_n_cycles += 2;
+ break;
+ case sz_word:
+ insn_n_cycles += 2;
+ break;
+ case sz_long:
+ insn_n_cycles += 4;
+ break;
+ default:
+ assert(0);
+ break;
+ }
+ start_brace();
+ comprintf("\tint %s = scratchie++;\n", name);
+ switch (size)
+ {
+ case sz_byte:
+ gen_readbyte(astring, name);
+ break;
+ case sz_word:
+ gen_readword(astring, name);
+ break;
+ case sz_long:
+ gen_readlong(astring, name);
+ break;
+ default:
+ assert(0);
+ break;
+ }
}
- start_brace ();
- comprintf("\tint %s=scratchie++;\n",name);
- switch (size)
+
+ /* We now might have to fix up the register for pre-dec or post-inc
+ * addressing modes. */
+ if (movem == GENA_MOVEM_DO_INC)
{
- case sz_byte:
- gen_readbyte(astring,name);
- break;
- case sz_word:
- gen_readword(astring,name);
- break;
- case sz_long:
- gen_readlong(astring,name);
- break;
- default:
- assert(0);
+ switch (mode)
+ {
+ case Aipi:
+ switch (size)
+ {
+ case sz_byte:
+ comprintf("\tlea_l_brr(%s + 8,%s + 8, areg_byteinc[%s]);\n", reg, reg, reg);
+ break;
+ case sz_word:
+ comprintf("\tlea_l_brr(%s + 8, %s + 8, 2);\n", reg, reg);
+ break;
+ case sz_long:
+ comprintf("\tlea_l_brr(%s + 8, %s + 8, 4);\n", reg, reg);
+ break;
+ default:
+ assert(0);
+ break;
+ }
+ break;
+ case Apdi:
+ break;
+ default:
+ break;
+ }
}
- }
+}
- /* We now might have to fix up the register for pre-dec or post-inc
- * addressing modes. */
- if (!movem) {
-// MJ char x[160];
+static void genastore(const char *from, amodes mode, const char *reg, wordsizes size, const char *to)
+{
switch (mode)
{
- case Aipi:
- switch (size)
- {
- case sz_byte:
- comprintf("\tlea_l_brr(%s+8,%s+8,areg_byteinc[%s]);\n",reg,reg,reg);
- break;
- case sz_word:
- comprintf("\tlea_l_brr(%s+8,%s+8,2);\n",reg,reg,reg);
+ case Dreg:
+ switch (size)
+ {
+ case sz_byte:
+ comprintf("\tif(%s != %s)\n", reg, from);
+ comprintf("\t\tmov_b_rr(%s, %s);\n", reg, from);
+ break;
+ case sz_word:
+ comprintf("\tif(%s != %s)\n", reg, from);
+ comprintf("\t\tmov_w_rr(%s, %s);\n", reg, from);
+ break;
+ case sz_long:
+ comprintf("\tif(%s != %s)\n", reg, from);
+ comprintf("\t\tmov_l_rr(%s, %s);\n", reg, from);
+ break;
+ default:
+ assert(0);
+ break;
+ }
break;
- case sz_long:
- comprintf("\tlea_l_brr(%s+8,%s+8,4);\n",reg,reg);
+ case Areg:
+ switch (size)
+ {
+ case sz_word:
+ comprintf("\tif(%s + 8 != %s)\n", reg, from);
+ comprintf("\t\tmov_w_rr(%s + 8, %s);\n", reg, from);
+ break;
+ case sz_long:
+ comprintf("\tif(%s + 8 != %s)\n", reg, from);
+ comprintf("\t\tmov_l_rr(%s + 8, %s);\n", reg, from);
+ break;
+ default:
+ assert(0);
+ break;
+ }
break;
- default:
- assert(0);
- }
- break;
- case Apdi:
- break;
- default:
- break;
- }
- }
-}
-static void
-genastore (const char *from, amodes mode, const char *reg, wordsizes size, const char *to)
-{
- switch (mode)
- {
- case Dreg:
- switch (size)
+ case Apdi:
+ case absw:
+ case PC16:
+ case PC8r:
+ case Ad16:
+ case Ad8r:
+ case Aipi:
+ case Aind:
+ case absl:
{
- case sz_byte:
- comprintf("\tif(%s!=%s)\n",reg,from);
- comprintf ("\t\tmov_b_rr(%s,%s);\n", reg, from);
- break;
- case sz_word:
- comprintf("\tif(%s!=%s)\n",reg,from);
- comprintf ("\t\tmov_w_rr(%s,%s);\n", reg, from);
- break;
- case sz_long:
- comprintf("\tif(%s!=%s)\n",reg,from);
- comprintf ("\t\tmov_l_rr(%s,%s);\n", reg, from);
- break;
- default:
- assert(0);
+ char astring[80];
+ sprintf(astring, "%sa", to);
+
+ switch (size)
+ {
+ case sz_byte:
+ insn_n_cycles += 2;
+ gen_writebyte(astring, from);
+ break;
+ case sz_word:
+ insn_n_cycles += 2;
+ gen_writeword(astring, from);
+ break;
+ case sz_long:
+ insn_n_cycles += 4;
+ gen_writelong(astring, from);
+ break;
+ default:
+ assert(0);
+ break;
+ }
}
break;
- case Areg:
- switch (size)
- {
- case sz_word:
- comprintf("\tif(%s+8!=%s)\n",reg,from);
- comprintf ("\t\tmov_w_rr(%s+8,%s);\n", reg, from);
- break;
- case sz_long:
- comprintf("\tif(%s+8!=%s)\n",reg,from);
- comprintf ("\t\tmov_l_rr(%s+8,%s);\n", reg, from);
- break;
- default:
- assert(0);
+ case imm:
+ case imm0:
+ case imm1:
+ case imm2:
+ case immi:
+ assert(0);
+ break;
+ default:
+ assert(0);
+ break;
}
- break;
-
- case Apdi:
- case absw:
- case PC16:
- case PC8r:
- case Ad16:
- case Ad8r:
- case Aipi:
- case Aind:
- case absl:
- {
- char astring[80];
- sprintf(astring,"%sa",to);
-
- switch (size)
- {
- case sz_byte:
- insn_n_cycles += 2;
- gen_writebyte(astring,from);
- break;
- case sz_word:
- insn_n_cycles += 2;
- gen_writeword(astring,from);
- break;
- case sz_long:
- insn_n_cycles += 4;
- gen_writelong(astring,from);
- break;
- default:
- assert(0);
- }
- }
- break;
- case imm:
- case imm0:
- case imm1:
- case imm2:
- case immi:
- assert(0);
- break;
- default:
- assert(0);
- }
}
static void genmov16(uae_u32 opcode, struct instr *curi)
comprintf("\tuae_u16 dstreg=((%s)>>12)&0x07;\n", gen_nextiword());
comprintf("\tmov_l_rr(src,8+srcreg);\n");
comprintf("\tmov_l_rr(dst,8+dstreg);\n");
- }
- else {
+ } else {
/* Other variants */
- genamode (curi->smode, "srcreg", curi->size, "src", 0, 2);
- genamode (curi->dmode, "dstreg", curi->size, "dst", 0, 2);
+ genamode(curi->smode, "srcreg", curi->size, "src", GENA_GETV_NO_FETCH, GENA_MOVEM_MOVE16);
+ genamode(curi->dmode, "dstreg", curi->size, "dst", GENA_GETV_NO_FETCH, GENA_MOVEM_MOVE16);
comprintf("\tmov_l_rr(src,srca);\n");
comprintf("\tmov_l_rr(dst,dsta);\n");
}
comprintf("\tif (srcreg != dstreg)\n");
comprintf("\tadd_l_ri(srcreg+8,16);\n");
comprintf("\tadd_l_ri(dstreg+8,16);\n");
- }
- else if ((opcode & 0xfff8) == 0xf600)
+ } else if ((opcode & 0xfff8) == 0xf600)
comprintf("\tadd_l_ri(srcreg+8,16);\n");
else if ((opcode & 0xfff8) == 0xf608)
comprintf("\tadd_l_ri(dstreg+8,16);\n");
comprintf("\tif (special_mem) {\n");
comprintf("\t\tint tmp=scratchie;\n");
comprintf("\tscratchie+=4;\n"
- "\treadlong(src,tmp,scratchie);\n"
- "\twritelong_clobber(dst,tmp,scratchie);\n"
- "\tadd_l_ri(src,4);\n"
- "\tadd_l_ri(dst,4);\n"
- "\treadlong(src,tmp,scratchie);\n"
- "\twritelong_clobber(dst,tmp,scratchie);\n"
- "\tadd_l_ri(src,4);\n"
- "\tadd_l_ri(dst,4);\n"
- "\treadlong(src,tmp,scratchie);\n"
- "\twritelong_clobber(dst,tmp,scratchie);\n"
- "\tadd_l_ri(src,4);\n"
- "\tadd_l_ri(dst,4);\n"
- "\treadlong(src,tmp,scratchie);\n"
- "\twritelong_clobber(dst,tmp,scratchie);\n");
- comprintf("\t} else {\n");
+ "\treadlong(src,tmp,scratchie);\n"
+ "\twritelong_clobber(dst,tmp,scratchie);\n"
+ "\tadd_l_ri(src,4);\n"
+ "\tadd_l_ri(dst,4);\n"
+ "\treadlong(src,tmp,scratchie);\n"
+ "\twritelong_clobber(dst,tmp,scratchie);\n"
+ "\tadd_l_ri(src,4);\n"
+ "\tadd_l_ri(dst,4);\n"
+ "\treadlong(src,tmp,scratchie);\n"
+ "\twritelong_clobber(dst,tmp,scratchie);\n"
+ "\tadd_l_ri(src,4);\n"
+ "\tadd_l_ri(dst,4);\n"
+ "\treadlong(src,tmp,scratchie);\n"
+ "\twritelong_clobber(dst,tmp,scratchie);\n");
+ comprintf("\t} else\n");
#endif
+ start_brace();
comprintf("\tint tmp=scratchie;\n");
comprintf("\tscratchie+=4;\n"
"\tget_n_addr(src,src,scratchie);\n"
"\tmov_l_Rr(dst,tmp+2,8);\n"
"\tforget_about(tmp+2);\n"
"\tmov_l_Rr(dst,tmp+3,12);\n");
-#ifdef UAE
- comprintf("\t}\n");
-#endif
+ close_brace();
}
static void
-genmovemel (uae_u16 opcode)
+genmovemel(uae_u16 opcode)
{
- comprintf ("\tuae_u16 mask = %s;\n", gen_nextiword ());
- comprintf ("\tint native=scratchie++;\n");
- comprintf ("\tint i;\n");
- comprintf ("\tsigned char offset=0;\n");
- genamode (table68k[opcode].dmode, "dstreg", table68k[opcode].size, "src", 2, 1);
+ comprintf("\tuae_u16 mask = %s;\n", gen_nextiword());
+ comprintf("\tint native=scratchie++;\n");
+ comprintf("\tint i;\n");
+ comprintf("\tsigned char offset=0;\n");
+ genamode(table68k[opcode].dmode, "dstreg", table68k[opcode].size, "src", GENA_GETV_FETCH_ALIGN, GENA_MOVEM_NO_INC);
#ifdef UAE
if (table68k[opcode].size == sz_long)
- comprintf("\tif (1 && !special_mem) {\n");
+ comprintf("\tif (1 && !special_mem) {\n");
else
- comprintf("\tif (1 && !special_mem) {\n");
+ comprintf("\tif (1 && !special_mem) {\n");
#endif
- /* Fast but unsafe... */
- comprintf("\tget_n_addr(srca,native,scratchie);\n");
+ /* Fast but unsafe... */
+ comprintf("\tget_n_addr(srca,native,scratchie);\n");
- comprintf("\tfor (i=0;i<16;i++) {\n"
- "\t\tif ((mask>>i)&1) {\n");
- switch(table68k[opcode].size) {
- case sz_long:
- comprintf("\t\t\tmov_l_rR(i,native,offset);\n"
- "\t\t\tmid_bswap_32(i);\n"
- "\t\t\toffset+=4;\n");
- break;
- case sz_word:
- comprintf("\t\t\tmov_w_rR(i,native,offset);\n"
- "\t\t\tmid_bswap_16(i);\n"
- "\t\t\tsign_extend_16_rr(i,i);\n"
- "\t\t\toffset+=2;\n");
- break;
- default: assert(0);
- }
- comprintf("\t\t}\n"
- "\t}");
- if (table68k[opcode].dmode == Aipi) {
- comprintf("\t\t\tlea_l_brr(8+dstreg,srca,offset);\n");
- }
- /* End fast but unsafe. */
+ comprintf("\tfor (i=0;i<16;i++) {\n"
+ "\t\tif ((mask>>i)&1) {\n");
+ switch (table68k[opcode].size) {
+ case sz_long:
+ comprintf("\t\t\tmov_l_rR(i,native,offset);\n"
+ "\t\t\tmid_bswap_32(i);\n"
+ "\t\t\toffset+=4;\n");
+ break;
+ case sz_word:
+ comprintf("\t\t\tmov_w_rR(i,native,offset);\n"
+ "\t\t\tmid_bswap_16(i);\n"
+ "\t\t\tsign_extend_16_rr(i,i);\n"
+ "\t\t\toffset+=2;\n");
+ break;
+ default: assert(0);
+ }
+ comprintf("\t\t}\n"
+ "\t}");
+ if (table68k[opcode].dmode == Aipi) {
+ comprintf("\t\t\tlea_l_brr(8+dstreg,srca,offset);\n");
+ }
+ /* End fast but unsafe. */
#ifdef UAE
- comprintf("\t} else {\n");
+ comprintf("\t} else {\n");
- comprintf ("\t\tint tmp=scratchie++;\n");
+ comprintf("\t\tint tmp=scratchie++;\n");
- comprintf("\t\tmov_l_rr(tmp,srca);\n");
- comprintf("\t\tfor (i=0;i<16;i++) {\n"
- "\t\t\tif ((mask>>i)&1) {\n");
- switch(table68k[opcode].size) {
- case sz_long:
- comprintf("\t\t\t\treadlong(tmp,i,scratchie);\n"
- "\t\t\t\tadd_l_ri(tmp,4);\n");
- break;
- case sz_word:
- comprintf("\t\t\t\treadword(tmp,i,scratchie);\n"
- "\t\t\t\tadd_l_ri(tmp,2);\n");
- break;
- default: assert(0);
- }
+ comprintf("\t\tmov_l_rr(tmp,srca);\n");
+ comprintf("\t\tfor (i=0;i<16;i++) {\n"
+ "\t\t\tif ((mask>>i)&1) {\n");
+ switch (table68k[opcode].size) {
+ case sz_long:
+ comprintf("\t\t\t\treadlong(tmp,i,scratchie);\n"
+ "\t\t\t\tadd_l_ri(tmp,4);\n");
+ break;
+ case sz_word:
+ comprintf("\t\t\t\treadword(tmp,i,scratchie);\n"
+ "\t\t\t\tadd_l_ri(tmp,2);\n");
+ break;
+ default: assert(0);
+ }
- comprintf("\t\t\t}\n"
- "\t\t}\n");
- if (table68k[opcode].dmode == Aipi) {
- comprintf("\t\tmov_l_rr(8+dstreg,tmp);\n");
- }
- comprintf("\t}\n");
+ comprintf("\t\t\t}\n"
+ "\t\t}\n");
+ if (table68k[opcode].dmode == Aipi) {
+ comprintf("\t\tmov_l_rr(8+dstreg,tmp);\n");
+ }
+ comprintf("\t}\n");
#endif
}
static void
-genmovemle (uae_u16 opcode)
+genmovemle(uae_u16 opcode)
{
- comprintf ("\tuae_u16 mask = %s;\n", gen_nextiword ());
- comprintf ("\tint native=scratchie++;\n");
- comprintf ("\tint i;\n");
- comprintf ("\tint tmp=scratchie++;\n");
- comprintf ("\tsigned char offset=0;\n");
- genamode (table68k[opcode].dmode, "dstreg", table68k[opcode].size, "src", 2, 1);
+ comprintf("\tuae_u16 mask = %s;\n", gen_nextiword());
+ comprintf("\tint native=scratchie++;\n");
+ comprintf("\tint i;\n");
+ comprintf("\tint tmp=scratchie++;\n");
+ comprintf("\tsigned char offset=0;\n");
+ genamode(table68k[opcode].dmode, "dstreg", table68k[opcode].size, "src", GENA_GETV_FETCH_ALIGN, GENA_MOVEM_NO_INC);
#ifdef UAE
- /* *Sigh* Some clever geek realized that the fastest way to copy a
- buffer from main memory to the gfx card is by using movmle. Good
- on her, but unfortunately, gfx mem isn't "real" mem, and thus that
- act of cleverness means that movmle must pay attention to special_mem,
- or Genetic Species is a rather boring-looking game ;-) */
+ /* *Sigh* Some clever geek realized that the fastest way to copy a
+ buffer from main memory to the gfx card is by using movmle. Good
+ on her, but unfortunately, gfx mem isn't "real" mem, and thus that
+ act of cleverness means that movmle must pay attention to special_mem,
+ or Genetic Species is a rather boring-looking game ;-) */
if (table68k[opcode].size == sz_long)
- comprintf("\tif (1 && !special_mem) {\n");
+ comprintf("\tif (1 && !special_mem) {\n");
else
- comprintf("\tif (1 && !special_mem) {\n");
+ comprintf("\tif (1 && !special_mem) {\n");
#endif
- comprintf("\tget_n_addr(srca,native,scratchie);\n");
+ comprintf("\tget_n_addr(srca,native,scratchie);\n");
- if (table68k[opcode].dmode!=Apdi) {
- comprintf("\tfor (i=0;i<16;i++) {\n"
- "\t\tif ((mask>>i)&1) {\n");
- switch(table68k[opcode].size) {
- case sz_long:
- comprintf("\t\t\tmov_l_rr(tmp,i);\n"
- "\t\t\tmid_bswap_32(tmp);\n"
- "\t\t\tmov_l_Rr(native,tmp,offset);\n"
- "\t\t\toffset+=4;\n");
- break;
- case sz_word:
- comprintf("\t\t\tmov_l_rr(tmp,i);\n"
- "\t\t\tmid_bswap_16(tmp);\n"
- "\t\t\tmov_w_Rr(native,tmp,offset);\n"
- "\t\t\toffset+=2;\n");
- break;
- default: assert(0);
- }
- }
- else { /* Pre-decrement */
- comprintf("\tfor (i=0;i<16;i++) {\n"
- "\t\tif ((mask>>i)&1) {\n");
- switch(table68k[opcode].size) {
- case sz_long:
- comprintf("\t\t\toffset-=4;\n"
- "\t\t\tmov_l_rr(tmp,15-i);\n"
- "\t\t\tmid_bswap_32(tmp);\n"
- "\t\t\tmov_l_Rr(native,tmp,offset);\n"
- );
- break;
- case sz_word:
- comprintf("\t\t\toffset-=2;\n"
- "\t\t\tmov_l_rr(tmp,15-i);\n"
- "\t\t\tmid_bswap_16(tmp);\n"
- "\t\t\tmov_w_Rr(native,tmp,offset);\n"
- );
- break;
- default: assert(0);
+ if (table68k[opcode].dmode != Apdi) {
+ comprintf("\tfor (i=0;i<16;i++) {\n"
+ "\t\tif ((mask>>i)&1) {\n");
+ switch (table68k[opcode].size) {
+ case sz_long:
+ comprintf("\t\t\tmov_l_rr(tmp,i);\n"
+ "\t\t\tmid_bswap_32(tmp);\n"
+ "\t\t\tmov_l_Rr(native,tmp,offset);\n"
+ "\t\t\toffset+=4;\n");
+ break;
+ case sz_word:
+ comprintf("\t\t\tmov_l_rr(tmp,i);\n"
+ "\t\t\tmid_bswap_16(tmp);\n"
+ "\t\t\tmov_w_Rr(native,tmp,offset);\n"
+ "\t\t\toffset+=2;\n");
+ break;
+ default: assert(0);
+ }
+ } else { /* Pre-decrement */
+ comprintf("\tfor (i=0;i<16;i++) {\n"
+ "\t\tif ((mask>>i)&1) {\n");
+ switch (table68k[opcode].size) {
+ case sz_long:
+ comprintf("\t\t\toffset-=4;\n"
+ "\t\t\tmov_l_rr(tmp,15-i);\n"
+ "\t\t\tmid_bswap_32(tmp);\n"
+ "\t\t\tmov_l_Rr(native,tmp,offset);\n"
+ );
+ break;
+ case sz_word:
+ comprintf("\t\t\toffset-=2;\n"
+ "\t\t\tmov_l_rr(tmp,15-i);\n"
+ "\t\t\tmid_bswap_16(tmp);\n"
+ "\t\t\tmov_w_Rr(native,tmp,offset);\n"
+ );
+ break;
+ default: assert(0);
+ }
}
- }
- comprintf("\t\t}\n"
- "\t}");
- if (table68k[opcode].dmode == Apdi) {
- comprintf("\t\t\tlea_l_brr(8+dstreg,srca,(uae_s32)offset);\n");
- }
+ comprintf("\t\t}\n"
+ "\t}");
+ if (table68k[opcode].dmode == Apdi) {
+ comprintf("\t\t\tlea_l_brr(8+dstreg,srca,(uae_s32)offset);\n");
+ }
#ifdef UAE
- comprintf("\t} else {\n");
+ comprintf("\t} else {\n");
- if (table68k[opcode].dmode!=Apdi) {
- comprintf("\tmov_l_rr(tmp,srca);\n");
- comprintf("\tfor (i=0;i<16;i++) {\n"
- "\t\tif ((mask>>i)&1) {\n");
- switch(table68k[opcode].size) {
- case sz_long:
- comprintf("\t\t\twritelong(tmp,i,scratchie);\n"
- "\t\t\tadd_l_ri(tmp,4);\n");
- break;
- case sz_word:
- comprintf("\t\t\twriteword(tmp,i,scratchie);\n"
- "\t\t\tadd_l_ri(tmp,2);\n");
- break;
- default: assert(0);
- }
- }
- else { /* Pre-decrement */
- comprintf("\tfor (i=0;i<16;i++) {\n"
- "\t\tif ((mask>>i)&1) {\n");
- switch(table68k[opcode].size) {
- case sz_long:
- comprintf("\t\t\tsub_l_ri(srca,4);\n"
- "\t\t\twritelong(srca,15-i,scratchie);\n");
- break;
- case sz_word:
- comprintf("\t\t\tsub_l_ri(srca,2);\n"
- "\t\t\twriteword(srca,15-i,scratchie);\n");
- break;
- default: assert(0);
+ if (table68k[opcode].dmode != Apdi) {
+ comprintf("\tmov_l_rr(tmp,srca);\n");
+ comprintf("\tfor (i=0;i<16;i++) {\n"
+ "\t\tif ((mask>>i)&1) {\n");
+ switch (table68k[opcode].size) {
+ case sz_long:
+ comprintf("\t\t\twritelong(tmp,i,scratchie);\n"
+ "\t\t\tadd_l_ri(tmp,4);\n");
+ break;
+ case sz_word:
+ comprintf("\t\t\twriteword(tmp,i,scratchie);\n"
+ "\t\t\tadd_l_ri(tmp,2);\n");
+ break;
+ default: assert(0);
+ }
+ } else { /* Pre-decrement */
+ comprintf("\tfor (i=0;i<16;i++) {\n"
+ "\t\tif ((mask>>i)&1) {\n");
+ switch (table68k[opcode].size) {
+ case sz_long:
+ comprintf("\t\t\tsub_l_ri(srca,4);\n"
+ "\t\t\twritelong(srca,15-i,scratchie);\n");
+ break;
+ case sz_word:
+ comprintf("\t\t\tsub_l_ri(srca,2);\n"
+ "\t\t\twriteword(srca,15-i,scratchie);\n");
+ break;
+ default: assert(0);
+ }
}
- }
- comprintf("\t\t}\n"
- "\t}");
- if (table68k[opcode].dmode == Apdi) {
- comprintf("\t\t\tmov_l_rr(8+dstreg,srca);\n");
- }
- comprintf("\t}\n");
+ comprintf("\t\t}\n"
+ "\t}");
+ if (table68k[opcode].dmode == Apdi) {
+ comprintf("\t\t\tmov_l_rr(8+dstreg,srca);\n");
+ }
+ comprintf("\t}\n");
#endif
}
static void
-duplicate_carry (void)
+duplicate_carry(void)
{
- comprintf ("\tif (needed_flags&FLAG_X) duplicate_carry();\n");
+ comprintf("\tif (needed_flags&FLAG_X) duplicate_carry();\n");
}
typedef enum
{
- flag_logical_noclobber, flag_logical, flag_add, flag_sub, flag_cmp,
- flag_addx, flag_subx, flag_zn, flag_av, flag_sv, flag_and, flag_or,
- flag_eor, flag_mov
+ flag_logical_noclobber, flag_logical, flag_add, flag_sub, flag_cmp,
+ flag_addx, flag_subx, flag_zn, flag_av, flag_sv, flag_and, flag_or,
+ flag_eor, flag_mov
}
flagtypes;
static void
-genflags (flagtypes type, wordsizes size, const char *value, const char *src, const char *dst)
+genflags(flagtypes type, wordsizes size, const char *value, const char *src, const char *dst)
{
- if (noflags) {
- switch(type) {
- case flag_cmp:
- comprintf("\tdont_care_flags();\n");
- comprintf("/* Weird --- CMP with noflags ;-) */\n");
- return;
- case flag_add:
- case flag_sub:
- comprintf("\tdont_care_flags();\n");
- {
- const char* op;
- switch(type) {
- case flag_add: op="add"; break;
- case flag_sub: op="sub"; break;
- default: assert(0);
+ if (noflags) {
+ switch (type) {
+ case flag_cmp:
+ comprintf("\tdont_care_flags();\n");
+ comprintf("/* Weird --- CMP with noflags ;-) */\n");
+ return;
+ case flag_add:
+ case flag_sub:
+ comprintf("\tdont_care_flags();\n");
+ {
+ const char *op;
+ switch (type) {
+ case flag_add: op = "add"; break;
+ case flag_sub: op = "sub"; break;
+ default: assert(0);
+ }
+ switch (size)
+ {
+ case sz_byte:
+ comprintf("\t%s_b(%s,%s);\n", op, dst, src);
+ break;
+ case sz_word:
+ comprintf("\t%s_w(%s,%s);\n", op, dst, src);
+ break;
+ case sz_long:
+ comprintf("\t%s_l(%s,%s);\n", op, dst, src);
+ break;
+ }
+ return;
+ }
+ break;
+
+ case flag_and:
+ comprintf("\tdont_care_flags();\n");
+ switch (size)
+ {
+ case sz_byte:
+ comprintf("if (kill_rodent(dst)) {\n");
+ comprintf("\tzero_extend_8_rr(scratchie,%s);\n", src);
+ comprintf("\tor_l_ri(scratchie,0xffffff00);\n");
+ comprintf("\tand_l(%s,scratchie);\n", dst);
+ comprintf("\tforget_about(scratchie);\n");
+ comprintf("\t} else \n"
+ "\tand_b(%s,%s);\n", dst, src);
+ break;
+ case sz_word:
+ comprintf("if (kill_rodent(dst)) {\n");
+ comprintf("\tzero_extend_16_rr(scratchie,%s);\n", src);
+ comprintf("\tor_l_ri(scratchie,0xffff0000);\n");
+ comprintf("\tand_l(%s,scratchie);\n", dst);
+ comprintf("\tforget_about(scratchie);\n");
+ comprintf("\t} else \n"
+ "\tand_w(%s,%s);\n", dst, src);
+ break;
+ case sz_long:
+ comprintf("\tand_l(%s,%s);\n", dst, src);
+ break;
+ }
+ return;
+
+ case flag_mov:
+ comprintf("\tdont_care_flags();\n");
+ switch (size)
+ {
+ case sz_byte:
+ comprintf("if (kill_rodent(dst)) {\n");
+ comprintf("\tzero_extend_8_rr(scratchie,%s);\n", src);
+ comprintf("\tand_l_ri(%s,0xffffff00);\n", dst);
+ comprintf("\tor_l(%s,scratchie);\n", dst);
+ comprintf("\tforget_about(scratchie);\n");
+ comprintf("\t} else \n"
+ "\tmov_b_rr(%s,%s);\n", dst, src);
+ break;
+ case sz_word:
+ comprintf("if (kill_rodent(dst)) {\n");
+ comprintf("\tzero_extend_16_rr(scratchie,%s);\n", src);
+ comprintf("\tand_l_ri(%s,0xffff0000);\n", dst);
+ comprintf("\tor_l(%s,scratchie);\n", dst);
+ comprintf("\tforget_about(scratchie);\n");
+ comprintf("\t} else \n"
+ "\tmov_w_rr(%s,%s);\n", dst, src);
+ break;
+ case sz_long:
+ comprintf("\tmov_l_rr(%s,%s);\n", dst, src);
+ break;
+ }
+ return;
+
+ case flag_or:
+ case flag_eor:
+ comprintf("\tdont_care_flags();\n");
+ start_brace();
+ {
+ const char *op;
+ switch (type) {
+ case flag_or: op = "or"; break;
+ case flag_eor: op = "xor"; break;
+ default: assert(0);
+ }
+ switch (size)
+ {
+ case sz_byte:
+ comprintf("if (kill_rodent(dst)) {\n");
+ comprintf("\tzero_extend_8_rr(scratchie,%s);\n", src);
+ comprintf("\t%s_l(%s,scratchie);\n", op, dst);
+ comprintf("\tforget_about(scratchie);\n");
+ comprintf("\t} else \n"
+ "\t%s_b(%s,%s);\n", op, dst, src);
+ break;
+ case sz_word:
+ comprintf("if (kill_rodent(dst)) {\n");
+ comprintf("\tzero_extend_16_rr(scratchie,%s);\n", src);
+ comprintf("\t%s_l(%s,scratchie);\n", op, dst);
+ comprintf("\tforget_about(scratchie);\n");
+ comprintf("\t} else \n"
+ "\t%s_w(%s,%s);\n", op, dst, src);
+ break;
+ case sz_long:
+ comprintf("\t%s_l(%s,%s);\n", op, dst, src);
+ break;
+ }
+ close_brace();
+ return;
+ }
+
+
+ case flag_addx:
+ case flag_subx:
+ comprintf("\tdont_care_flags();\n");
+ {
+ const char *op;
+ switch (type) {
+ case flag_addx: op = "adc"; break;
+ case flag_subx: op = "sbb"; break;
+ default: assert(0);
+ }
+ comprintf("\trestore_carry();\n"); /* Reload the X flag into C */
+ switch (size)
+ {
+ case sz_byte:
+ comprintf("\t%s_b(%s,%s);\n", op, dst, src);
+ break;
+ case sz_word:
+ comprintf("\t%s_w(%s,%s);\n", op, dst, src);
+ break;
+ case sz_long:
+ comprintf("\t%s_l(%s,%s);\n", op, dst, src);
+ break;
+ }
+ return;
+ }
+ break;
+ default: return;
}
- switch (size)
+ }
+
+ /* Need the flags, but possibly not all of them */
+ switch (type)
+ {
+ case flag_logical_noclobber:
+ failure;
+ /* fall through */
+
+ case flag_and:
+ case flag_or:
+ case flag_eor:
+ comprintf("\tdont_care_flags();\n");
+ start_brace();
{
- case sz_byte:
- comprintf("\t%s_b(%s,%s);\n",op,dst,src);
- break;
- case sz_word:
- comprintf("\t%s_w(%s,%s);\n",op,dst,src);
- break;
- case sz_long:
- comprintf("\t%s_l(%s,%s);\n",op,dst,src);
- break;
+ const char *op;
+ switch (type) {
+ case flag_and: op = "and"; break;
+ case flag_or: op = "or"; break;
+ case flag_eor: op = "xor"; break;
+ default: assert(0);
+ }
+ switch (size)
+ {
+ case sz_byte:
+ comprintf("\tstart_needflags();\n"
+ "\t%s_b(%s,%s);\n", op, dst, src);
+ break;
+ case sz_word:
+ comprintf("\tstart_needflags();\n"
+ "\t%s_w(%s,%s);\n", op, dst, src);
+ break;
+ case sz_long:
+ comprintf("\tstart_needflags();\n"
+ "\t%s_l(%s,%s);\n", op, dst, src);
+ break;
+ }
+ comprintf("\tlive_flags();\n");
+ comprintf("\tend_needflags();\n");
+ close_brace();
+ return;
}
- return;
- }
- break;
-
- case flag_and:
- comprintf("\tdont_care_flags();\n");
- switch (size)
- {
- case sz_byte:
- comprintf("if (kill_rodent(dst)) {\n");
- comprintf("\tzero_extend_8_rr(scratchie,%s);\n",src);
- comprintf("\tor_l_ri(scratchie,0xffffff00);\n");
- comprintf("\tand_l(%s,scratchie);\n",dst);
- comprintf("\tforget_about(scratchie);\n");
- comprintf("\t} else \n"
- "\tand_b(%s,%s);\n",dst,src);
- break;
- case sz_word:
- comprintf("if (kill_rodent(dst)) {\n");
- comprintf("\tzero_extend_16_rr(scratchie,%s);\n",src);
- comprintf("\tor_l_ri(scratchie,0xffff0000);\n");
- comprintf("\tand_l(%s,scratchie);\n",dst);
- comprintf("\tforget_about(scratchie);\n");
- comprintf("\t} else \n"
- "\tand_w(%s,%s);\n",dst,src);
- break;
- case sz_long:
- comprintf("\tand_l(%s,%s);\n",dst,src);
- break;
- }
- return;
-
- case flag_mov:
- comprintf("\tdont_care_flags();\n");
- switch (size)
- {
- case sz_byte:
- comprintf("if (kill_rodent(dst)) {\n");
- comprintf("\tzero_extend_8_rr(scratchie,%s);\n",src);
- comprintf("\tand_l_ri(%s,0xffffff00);\n",dst);
- comprintf("\tor_l(%s,scratchie);\n",dst);
- comprintf("\tforget_about(scratchie);\n");
- comprintf("\t} else \n"
- "\tmov_b_rr(%s,%s);\n",dst,src);
- break;
- case sz_word:
- comprintf("if (kill_rodent(dst)) {\n");
- comprintf("\tzero_extend_16_rr(scratchie,%s);\n",src);
- comprintf("\tand_l_ri(%s,0xffff0000);\n",dst);
- comprintf("\tor_l(%s,scratchie);\n",dst);
- comprintf("\tforget_about(scratchie);\n");
- comprintf("\t} else \n"
- "\tmov_w_rr(%s,%s);\n",dst,src);
- break;
- case sz_long:
- comprintf("\tmov_l_rr(%s,%s);\n",dst,src);
- break;
- }
- return;
-
- case flag_or:
- case flag_eor:
- comprintf("\tdont_care_flags();\n");
- start_brace();
- {
- const char* op;
- switch(type) {
- case flag_or: op="or"; break;
- case flag_eor: op="xor"; break;
- default: assert(0);
+
+ case flag_mov:
+ comprintf("\tdont_care_flags();\n");
+ start_brace();
+ {
+ switch (size)
+ {
+ case sz_byte:
+ comprintf("\tif (%s!=%s) {\n", src, dst);
+ comprintf("\tmov_b_ri(%s,0);\n"
+ "\tstart_needflags();\n", dst);
+ comprintf("\tor_b(%s,%s);\n", dst, src);
+ comprintf("\t} else {\n");
+ comprintf("\tmov_b_rr(%s,%s);\n", dst, src);
+ comprintf("\ttest_b_rr(%s,%s);\n", dst, dst);
+ comprintf("\t}\n");
+ break;
+ case sz_word:
+ comprintf("\tif (%s!=%s) {\n", src, dst);
+ comprintf("\tmov_w_ri(%s,0);\n"
+ "\tstart_needflags();\n", dst);
+ comprintf("\tor_w(%s,%s);\n", dst, src);
+ comprintf("\t} else {\n");
+ comprintf("\tmov_w_rr(%s,%s);\n", dst, src);
+ comprintf("\ttest_w_rr(%s,%s);\n", dst, dst);
+ comprintf("\t}\n");
+ break;
+ case sz_long:
+ comprintf("\tif (%s!=%s) {\n", src, dst);
+ comprintf("\tmov_l_ri(%s,0);\n"
+ "\tstart_needflags();\n", dst);
+ comprintf("\tor_l(%s,%s);\n", dst, src);
+ comprintf("\t} else {\n");
+ comprintf("\tmov_l_rr(%s,%s);\n", dst, src);
+ comprintf("\ttest_l_rr(%s,%s);\n", dst, dst);
+ comprintf("\t}\n");
+ break;
+ }
+ comprintf("\tlive_flags();\n");
+ comprintf("\tend_needflags();\n");
+ close_brace();
+ return;
}
+
+ case flag_logical:
+ comprintf("\tdont_care_flags();\n");
+ start_brace();
switch (size)
{
- case sz_byte:
- comprintf("if (kill_rodent(dst)) {\n");
- comprintf("\tzero_extend_8_rr(scratchie,%s);\n",src);
- comprintf("\t%s_l(%s,scratchie);\n",op,dst);
- comprintf("\tforget_about(scratchie);\n");
- comprintf("\t} else \n"
- "\t%s_b(%s,%s);\n",op,dst,src);
- break;
- case sz_word:
- comprintf("if (kill_rodent(dst)) {\n");
- comprintf("\tzero_extend_16_rr(scratchie,%s);\n",src);
- comprintf("\t%s_l(%s,scratchie);\n",op,dst);
- comprintf("\tforget_about(scratchie);\n");
- comprintf("\t} else \n"
- "\t%s_w(%s,%s);\n",op,dst,src);
- break;
- case sz_long:
- comprintf("\t%s_l(%s,%s);\n",op,dst,src);
- break;
+ case sz_byte:
+ comprintf("\tstart_needflags();\n"
+ "\ttest_b_rr(%s,%s);\n", value, value);
+ break;
+ case sz_word:
+ comprintf("\tstart_needflags();\n"
+ "\ttest_w_rr(%s,%s);\n", value, value);
+ break;
+ case sz_long:
+ comprintf("\tstart_needflags();\n"
+ "\ttest_l_rr(%s,%s);\n", value, value);
+ break;
}
+ comprintf("\tlive_flags();\n");
+ comprintf("\tend_needflags();\n");
close_brace();
return;
- }
- case flag_addx:
- case flag_subx:
- comprintf("\tdont_care_flags();\n");
- {
- const char* op;
- switch(type) {
- case flag_addx: op="adc"; break;
- case flag_subx: op="sbb"; break;
- default: assert(0);
+ case flag_add:
+ case flag_sub:
+ case flag_cmp:
+ comprintf("\tdont_care_flags();\n");
+ {
+ const char *op;
+ switch (type) {
+ case flag_add: op = "add"; break;
+ case flag_sub: op = "sub"; break;
+ case flag_cmp: op = "cmp"; break;
+ default: assert(0);
+ }
+ switch (size)
+ {
+ case sz_byte:
+ comprintf("\tstart_needflags();\n"
+ "\t%s_b(%s,%s);\n", op, dst, src);
+ break;
+ case sz_word:
+ comprintf("\tstart_needflags();\n"
+ "\t%s_w(%s,%s);\n", op, dst, src);
+ break;
+ case sz_long:
+ comprintf("\tstart_needflags();\n"
+ "\t%s_l(%s,%s);\n", op, dst, src);
+ break;
+ }
+ comprintf("\tlive_flags();\n");
+ comprintf("\tend_needflags();\n");
+ if (type != flag_cmp) {
+ duplicate_carry();
+ }
+ comprintf("if (!(needed_flags & FLAG_CZNV)) dont_care_flags();\n");
+
+ return;
}
- comprintf("\trestore_carry();\n"); /* Reload the X flag into C */
- switch (size)
+
+ case flag_addx:
+ case flag_subx:
+ uses_cmov;
+ comprintf("\tdont_care_flags();\n");
{
- case sz_byte:
- comprintf("\t%s_b(%s,%s);\n",op,dst,src);
- break;
- case sz_word:
- comprintf("\t%s_w(%s,%s);\n",op,dst,src);
- break;
- case sz_long:
- comprintf("\t%s_l(%s,%s);\n",op,dst,src);
- break;
+ const char *op;
+ switch (type) {
+ case flag_addx: op = "adc"; break;
+ case flag_subx: op = "sbb"; break;
+ default: assert(0);
+ }
+ start_brace();
+ comprintf("\tint zero=scratchie++;\n"
+ "\tint one=scratchie++;\n"
+ "\tif (needed_flags&FLAG_Z) {\n"
+ "\tmov_l_ri(zero,0);\n"
+ "\tmov_l_ri(one,-1);\n"
+ "\tmake_flags_live();\n"
+ "\tcmov_l_rr(zero,one,%d);\n"
+ "\t}\n", NATIVE_CC_NE);
+ comprintf("\trestore_carry();\n"); /* Reload the X flag into C */
+ switch (size)
+ {
+ case sz_byte:
+ comprintf("\tstart_needflags();\n"
+ "\t%s_b(%s,%s);\n", op, dst, src);
+ break;
+ case sz_word:
+ comprintf("\tstart_needflags();\n"
+ "\t%s_w(%s,%s);\n", op, dst, src);
+ break;
+ case sz_long:
+ comprintf("\tstart_needflags();\n"
+ "\t%s_l(%s,%s);\n", op, dst, src);
+ break;
+ }
+ comprintf("\tlive_flags();\n");
+ comprintf("\tif (needed_flags&FLAG_Z) {\n");
+ comprintf("\tcmov_l_rr(zero,one,%d);\n", NATIVE_CC_NE);
+ comprintf("\tset_zero(zero, one);\n"); /* No longer need one */
+ comprintf("\tlive_flags();\n");
+ comprintf("\t}\n");
+ comprintf("\tend_needflags();\n");
+ duplicate_carry();
+ comprintf("if (!(needed_flags & FLAG_CZNV)) dont_care_flags();\n");
+ return;
}
- return;
- }
- break;
- default: return;
- }
- }
-
- /* Need the flags, but possibly not all of them */
- switch (type)
- {
- case flag_logical_noclobber:
- failure;
-
- case flag_and:
- case flag_or:
- case flag_eor:
- comprintf("\tdont_care_flags();\n");
- start_brace();
- {
- const char* op;
- switch(type) {
- case flag_and: op="and"; break;
- case flag_or: op="or"; break;
- case flag_eor: op="xor"; break;
- default: assert(0);
- }
- switch (size)
- {
- case sz_byte:
- comprintf("\tstart_needflags();\n"
- "\t%s_b(%s,%s);\n",op,dst,src);
- break;
- case sz_word:
- comprintf("\tstart_needflags();\n"
- "\t%s_w(%s,%s);\n",op,dst,src);
- break;
- case sz_long:
- comprintf("\tstart_needflags();\n"
- "\t%s_l(%s,%s);\n",op,dst,src);
- break;
- }
- comprintf("\tlive_flags();\n");
- comprintf("\tend_needflags();\n");
- close_brace();
- return;
+ default:
+ failure;
+ break;
}
+}
- case flag_mov:
- comprintf("\tdont_care_flags();\n");
- start_brace();
- {
- switch (size)
- {
- case sz_byte:
- comprintf("\tif (%s!=%s) {\n",src,dst);
- comprintf("\tmov_b_ri(%s,0);\n"
- "\tstart_needflags();\n",dst);
- comprintf("\tor_b(%s,%s);\n",dst,src);
- comprintf("\t} else {\n");
- comprintf("\tmov_b_rr(%s,%s);\n",dst,src);
- comprintf("\ttest_b_rr(%s,%s);\n",dst,dst);
- comprintf("\t}\n");
- break;
- case sz_word:
- comprintf("\tif (%s!=%s) {\n",src,dst);
- comprintf("\tmov_w_ri(%s,0);\n"
- "\tstart_needflags();\n",dst);
- comprintf("\tor_w(%s,%s);\n",dst,src);
- comprintf("\t} else {\n");
- comprintf("\tmov_w_rr(%s,%s);\n",dst,src);
- comprintf("\ttest_w_rr(%s,%s);\n",dst,dst);
- comprintf("\t}\n");
- break;
- case sz_long:
- comprintf("\tif (%s!=%s) {\n",src,dst);
- comprintf("\tmov_l_ri(%s,0);\n"
- "\tstart_needflags();\n",dst);
- comprintf("\tor_l(%s,%s);\n",dst,src);
- comprintf("\t} else {\n");
- comprintf("\tmov_l_rr(%s,%s);\n",dst,src);
- comprintf("\ttest_l_rr(%s,%s);\n",dst,dst);
- comprintf("\t}\n");
- break;
- }
- comprintf("\tlive_flags();\n");
- comprintf("\tend_needflags();\n");
- close_brace();
- return;
- }
+static int /* returns zero for success, non-zero for failure */
+gen_opcode(unsigned int opcode)
+{
+ struct instr *curi = table68k + opcode;
+ const char *ssize = NULL;
+
+ insn_n_cycles = 2;
+ global_failure = 0;
+ long_opcode = 0;
+ global_isjump = 0;
+ global_iscjump = 0;
+ global_isaddx = 0;
+ global_cmov = 0;
+ global_fpu = 0;
+ global_mayfail = 0;
+ hack_opcode = opcode;
+ endstr[0] = 0;
- case flag_logical:
- comprintf("\tdont_care_flags();\n");
start_brace();
- switch (size)
+ comprintf("\tuae_u8 scratchie=S1;\n");
+ switch (curi->plev)
{
- case sz_byte:
- comprintf("\tstart_needflags();\n"
- "\ttest_b_rr(%s,%s);\n",value,value);
- break;
- case sz_word:
- comprintf("\tstart_needflags();\n"
- "\ttest_w_rr(%s,%s);\n",value,value);
- break;
- case sz_long:
- comprintf("\tstart_needflags();\n"
- "\ttest_l_rr(%s,%s);\n",value,value);
- break;
- }
- comprintf("\tlive_flags();\n");
- comprintf("\tend_needflags();\n");
- close_brace();
- return;
-
+ case 0: /* not privileged */
+ break;
+ case 1: /* unprivileged only on 68000 */
+ if (cpu_level == 0)
+ break;
+ if (next_cpu_level < 0)
+ next_cpu_level = 0;
- case flag_add:
- case flag_sub:
- case flag_cmp:
- comprintf("\tdont_care_flags();\n");
- {
- const char* op;
- switch(type) {
- case flag_add: op="add"; break;
- case flag_sub: op="sub"; break;
- case flag_cmp: op="cmp"; break;
- default: assert(0);
- }
- switch (size)
- {
- case sz_byte:
- comprintf("\tstart_needflags();\n"
- "\t%s_b(%s,%s);\n",op,dst,src);
- break;
- case sz_word:
- comprintf("\tstart_needflags();\n"
- "\t%s_w(%s,%s);\n",op,dst,src);
- break;
- case sz_long:
- comprintf("\tstart_needflags();\n"
- "\t%s_l(%s,%s);\n",op,dst,src);
- break;
- }
- comprintf("\tlive_flags();\n");
- comprintf("\tend_needflags();\n");
- if (type!=flag_cmp) {
- duplicate_carry();
- }
- comprintf("if (!(needed_flags & FLAG_CZNV)) dont_care_flags();\n");
-
- return;
+ /* fall through */
+ case 2: /* priviledged */
+ failure; /* Easy ones first */
+ break;
+ case 3: /* privileged if size == word */
+ if (curi->size == sz_byte)
+ break;
+ failure;
+ break;
}
-
- case flag_addx:
- case flag_subx:
- uses_cmov;
- comprintf("\tdont_care_flags();\n");
- {
- const char* op;
- switch(type) {
- case flag_addx: op="adc"; break;
- case flag_subx: op="sbb"; break;
- default: assert(0);
- }
- start_brace();
- comprintf("\tint zero=scratchie++;\n"
- "\tint one=scratchie++;\n"
- "\tif (needed_flags&FLAG_Z) {\n"
- "\tmov_l_ri(zero,0);\n"
- "\tmov_l_ri(one,-1);\n"
- "\tmake_flags_live();\n"
- "\tcmov_l_rr(zero,one,%d);\n"
- "\t}\n",NATIVE_CC_NE);
- comprintf("\trestore_carry();\n"); /* Reload the X flag into C */
- switch (size)
- {
- case sz_byte:
- comprintf("\tstart_needflags();\n"
- "\t%s_b(%s,%s);\n",op,dst,src);
- break;
- case sz_word:
- comprintf("\tstart_needflags();\n"
- "\t%s_w(%s,%s);\n",op,dst,src);
- break;
- case sz_long:
- comprintf("\tstart_needflags();\n"
- "\t%s_l(%s,%s);\n",op,dst,src);
- break;
- }
- comprintf("\tlive_flags();\n");
- comprintf("\tif (needed_flags&FLAG_Z) {\n");
- comprintf("\tcmov_l_rr(zero,one,%d);\n", NATIVE_CC_NE);
- comprintf("\tset_zero(zero, one);\n"); /* No longer need one */
- comprintf("\tlive_flags();\n");
- comprintf("\t}\n");
- comprintf("\tend_needflags();\n");
- duplicate_carry();
- comprintf("if (!(needed_flags & FLAG_CZNV)) dont_care_flags();\n");
- return;
+ switch (curi->size) {
+ case sz_byte: ssize = "b"; break;
+ case sz_word: ssize = "w"; break;
+ case sz_long: ssize = "l"; break;
+ default: assert(0);
}
- default:
- failure;
- break;
- }
-}
+ (void)ssize;
-static int /* returns zero for success, non-zero for failure */
-gen_opcode (unsigned int opcode)
-{
- struct instr *curi = table68k + opcode;
- const char* ssize=NULL;
-
- insn_n_cycles = 2;
- global_failure=0;
- long_opcode=0;
- global_isjump=0;
- global_iscjump=0;
- global_isaddx=0;
- global_cmov=0;
- global_fpu=0;
- global_mayfail=0;
- hack_opcode=opcode;
- endstr[0]=0;
-
- start_brace ();
- comprintf("\tuae_u8 scratchie=S1;\n");
- switch (curi->plev)
- {
- case 0: /* not privileged */
- break;
- case 1: /* unprivileged only on 68000 */
- if (cpu_level == 0)
- break;
- if (next_cpu_level < 0)
- next_cpu_level = 0;
-
- /* fall through */
- case 2: /* priviledged */
- failure; /* Easy ones first */
- break;
- case 3: /* privileged if size == word */
- if (curi->size == sz_byte)
- break;
- failure;
- break;
- }
- switch (curi->size) {
- case sz_byte: ssize="b"; break;
- case sz_word: ssize="w"; break;
- case sz_long: ssize="l"; break;
- default: assert(0);
- }
- (void)ssize;
-
- switch (curi->mnemo)
- {
- case i_OR:
- case i_AND:
- case i_EOR:
+ switch (curi->mnemo)
+ {
+ case i_OR:
+ case i_AND:
+ case i_EOR:
#ifdef DISABLE_I_OR_AND_EOR
- failure;
-#endif
- genamode (curi->smode, "srcreg", curi->size, "src", 1, 0);
- genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0);
- switch(curi->mnemo) {
- case i_OR: genflags (flag_or, curi->size, "", "src", "dst"); break;
- case i_AND: genflags (flag_and, curi->size, "", "src", "dst"); break;
- case i_EOR: genflags (flag_eor, curi->size, "", "src", "dst"); break;
- }
- genastore ("dst", curi->dmode, "dstreg", curi->size, "dst");
- break;
+ failure;
+#endif
+ genamode(curi->smode, "srcreg", curi->size, "src", GENA_GETV_FETCH, GENA_MOVEM_DO_INC);
+ genamode(curi->dmode, "dstreg", curi->size, "dst", GENA_GETV_FETCH, GENA_MOVEM_DO_INC);
+ switch (curi->mnemo) {
+ case i_OR: genflags(flag_or, curi->size, "", "src", "dst"); break;
+ case i_AND: genflags(flag_and, curi->size, "", "src", "dst"); break;
+ case i_EOR: genflags(flag_eor, curi->size, "", "src", "dst"); break;
+ }
+ genastore("dst", curi->dmode, "dstreg", curi->size, "dst");
+ break;
- case i_ORSR:
- case i_EORSR:
- failure;
- isjump;
- break;
+ case i_ORSR:
+ case i_EORSR:
+ failure;
+ isjump;
+ break;
- case i_ANDSR:
- failure;
- isjump;
- break;
+ case i_ANDSR:
+ failure;
+ isjump;
+ break;
- case i_SUB:
+ case i_SUB:
#ifdef DISABLE_I_SUB
- failure;
+ failure;
#endif
- genamode (curi->smode, "srcreg", curi->size, "src", 1, 0);
- genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0);
- genflags (flag_sub, curi->size, "", "src", "dst");
- genastore ("dst", curi->dmode, "dstreg", curi->size, "dst");
- break;
+ genamode(curi->smode, "srcreg", curi->size, "src", GENA_GETV_FETCH, GENA_MOVEM_DO_INC);
+ genamode(curi->dmode, "dstreg", curi->size, "dst", GENA_GETV_FETCH, GENA_MOVEM_DO_INC);
+ genflags(flag_sub, curi->size, "", "src", "dst");
+ genastore("dst", curi->dmode, "dstreg", curi->size, "dst");
+ break;
- case i_SUBA:
+ case i_SUBA:
#ifdef DISABLE_I_SUBA
- failure;
+ failure;
#endif
- genamode (curi->smode, "srcreg", curi->size, "src", 1, 0);
- genamode (curi->dmode, "dstreg", sz_long, "dst", 1, 0);
- start_brace();
- comprintf("\tint tmp=scratchie++;\n");
- switch(curi->size) {
- case sz_byte: comprintf("\tsign_extend_8_rr(tmp,src);\n"); break;
- case sz_word: comprintf("\tsign_extend_16_rr(tmp,src);\n"); break;
- case sz_long: comprintf("\ttmp=src;\n"); break;
- default: assert(0);
- }
- comprintf("\tsub_l(dst,tmp);\n");
- genastore ("dst", curi->dmode, "dstreg", sz_long, "dst");
- break;
+ genamode(curi->smode, "srcreg", curi->size, "src", GENA_GETV_FETCH, GENA_MOVEM_DO_INC);
+ genamode(curi->dmode, "dstreg", sz_long, "dst", GENA_GETV_FETCH, GENA_MOVEM_DO_INC);
+ start_brace();
+ comprintf("\tint tmp=scratchie++;\n");
+ switch (curi->size) {
+ case sz_byte: comprintf("\tsign_extend_8_rr(tmp,src);\n"); break;
+ case sz_word: comprintf("\tsign_extend_16_rr(tmp,src);\n"); break;
+ case sz_long: comprintf("\ttmp=src;\n"); break;
+ default: assert(0);
+ }
+ comprintf("\tsub_l(dst,tmp);\n");
+ genastore("dst", curi->dmode, "dstreg", sz_long, "dst");
+ break;
- case i_SUBX:
+ case i_SUBX:
#ifdef DISABLE_I_SUBX
- failure;
+ failure;
#endif
- isaddx;
- genamode (curi->smode, "srcreg", curi->size, "src", 1, 0);
- genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0);
- genflags (flag_subx, curi->size, "", "src", "dst");
- genastore ("dst", curi->dmode, "dstreg", curi->size, "dst");
- break;
+ isaddx;
+ genamode(curi->smode, "srcreg", curi->size, "src", GENA_GETV_FETCH, GENA_MOVEM_DO_INC);
+ genamode(curi->dmode, "dstreg", curi->size, "dst", GENA_GETV_FETCH, GENA_MOVEM_DO_INC);
+ genflags(flag_subx, curi->size, "", "src", "dst");
+ genastore("dst", curi->dmode, "dstreg", curi->size, "dst");
+ break;
- case i_SBCD:
- failure;
- /* I don't think so! */
- break;
+ case i_SBCD:
+ failure;
+ /* I don't think so! */
+ break;
- case i_ADD:
+ case i_ADD:
#ifdef DISABLE_I_ADD
- failure;
+ failure;
#endif
- genamode (curi->smode, "srcreg", curi->size, "src", 1, 0);
- genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0);
- genflags (flag_add, curi->size, "", "src", "dst");
- genastore ("dst", curi->dmode, "dstreg", curi->size, "dst");
- break;
+ genamode(curi->smode, "srcreg", curi->size, "src", GENA_GETV_FETCH, GENA_MOVEM_DO_INC);
+ genamode(curi->dmode, "dstreg", curi->size, "dst", GENA_GETV_FETCH, GENA_MOVEM_DO_INC);
+ genflags(flag_add, curi->size, "", "src", "dst");
+ genastore("dst", curi->dmode, "dstreg", curi->size, "dst");
+ break;
- case i_ADDA:
+ case i_ADDA:
#ifdef DISABLE_I_ADDA
- failure;
+ failure;
#endif
- genamode (curi->smode, "srcreg", curi->size, "src", 1, 0);
- genamode (curi->dmode, "dstreg", sz_long, "dst", 1, 0);
- start_brace();
- comprintf("\tint tmp=scratchie++;\n");
- switch(curi->size) {
- case sz_byte: comprintf("\tsign_extend_8_rr(tmp,src);\n"); break;
- case sz_word: comprintf("\tsign_extend_16_rr(tmp,src);\n"); break;
- case sz_long: comprintf("\ttmp=src;\n"); break;
- default: assert(0);
- }
- comprintf("\tadd_l(dst,tmp);\n");
- genastore ("dst", curi->dmode, "dstreg", sz_long, "dst");
- break;
+ genamode(curi->smode, "srcreg", curi->size, "src", GENA_GETV_FETCH, GENA_MOVEM_DO_INC);
+ genamode(curi->dmode, "dstreg", sz_long, "dst", GENA_GETV_FETCH, GENA_MOVEM_DO_INC);
+ start_brace();
+ comprintf("\tint tmp=scratchie++;\n");
+ switch (curi->size) {
+ case sz_byte: comprintf("\tsign_extend_8_rr(tmp,src);\n"); break;
+ case sz_word: comprintf("\tsign_extend_16_rr(tmp,src);\n"); break;
+ case sz_long: comprintf("\ttmp=src;\n"); break;
+ default: assert(0);
+ }
+ comprintf("\tadd_l(dst,tmp);\n");
+ genastore("dst", curi->dmode, "dstreg", sz_long, "dst");
+ break;
- case i_ADDX:
+ case i_ADDX:
#ifdef DISABLE_I_ADDX
- failure;
+ failure;
#endif
- isaddx;
- genamode (curi->smode, "srcreg", curi->size, "src", 1, 0);
- genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0);
- start_brace();
- genflags (flag_addx, curi->size, "", "src", "dst");
- genastore ("dst", curi->dmode, "dstreg", curi->size, "dst");
- break;
+ isaddx;
+ genamode(curi->smode, "srcreg", curi->size, "src", GENA_GETV_FETCH, GENA_MOVEM_DO_INC);
+ genamode(curi->dmode, "dstreg", curi->size, "dst", GENA_GETV_FETCH, GENA_MOVEM_DO_INC);
+ start_brace();
+ genflags(flag_addx, curi->size, "", "src", "dst");
+ genastore("dst", curi->dmode, "dstreg", curi->size, "dst");
+ break;
- case i_ABCD:
- failure;
- /* No BCD maths for me.... */
- break;
+ case i_ABCD:
+ failure;
+ /* No BCD maths for me.... */
+ break;
- case i_NEG:
+ case i_NEG:
#ifdef DISABLE_I_NEG
- failure;
+ failure;
#endif
- genamode (curi->smode, "srcreg", curi->size, "src", 1, 0);
- start_brace ();
- comprintf("\tint dst=scratchie++;\n");
- comprintf("\tmov_l_ri(dst,0);\n");
- genflags (flag_sub, curi->size, "", "src", "dst");
- genastore ("dst", curi->smode, "srcreg", curi->size, "src");
- break;
+ genamode(curi->smode, "srcreg", curi->size, "src", GENA_GETV_FETCH, GENA_MOVEM_DO_INC);
+ start_brace();
+ comprintf("\tint dst=scratchie++;\n");
+ comprintf("\tmov_l_ri(dst,0);\n");
+ genflags(flag_sub, curi->size, "", "src", "dst");
+ genastore("dst", curi->smode, "srcreg", curi->size, "src");
+ break;
- case i_NEGX:
+ case i_NEGX:
#ifdef DISABLE_I_NEGX
- failure;
+ failure;
#endif
- isaddx;
- genamode (curi->smode, "srcreg", curi->size, "src", 1, 0);
- start_brace ();
- comprintf("\tint dst=scratchie++;\n");
- comprintf("\tmov_l_ri(dst,0);\n");
- genflags (flag_subx, curi->size, "", "src", "dst");
- genastore ("dst", curi->smode, "srcreg", curi->size, "src");
- break;
+ isaddx;
+ genamode(curi->smode, "srcreg", curi->size, "src", GENA_GETV_FETCH, GENA_MOVEM_DO_INC);
+ start_brace();
+ comprintf("\tint dst=scratchie++;\n");
+ comprintf("\tmov_l_ri(dst,0);\n");
+ genflags(flag_subx, curi->size, "", "src", "dst");
+ genastore("dst", curi->smode, "srcreg", curi->size, "src");
+ break;
- case i_NBCD:
- failure;
- /* Nope! */
- break;
+ case i_NBCD:
+ failure;
+ /* Nope! */
+ break;
- case i_CLR:
+ case i_CLR:
#ifdef DISABLE_I_CLR
- failure;
+ failure;
#endif
- genamode (curi->smode, "srcreg", curi->size, "src", 2, 0);
- start_brace();
- comprintf("\tint dst=scratchie++;\n");
- comprintf("\tmov_l_ri(dst,0);\n");
- genflags (flag_logical, curi->size, "dst", "", "");
- genastore ("dst", curi->smode, "srcreg", curi->size, "src");
- break;
+ genamode(curi->smode, "srcreg", curi->size, "src", GENA_GETV_FETCH_ALIGN, GENA_MOVEM_DO_INC);
+ start_brace();
+ comprintf("\tint dst=scratchie++;\n");
+ comprintf("\tmov_l_ri(dst,0);\n");
+ genflags(flag_logical, curi->size, "dst", "", "");
+ genastore("dst", curi->smode, "srcreg", curi->size, "src");
+ break;
- case i_NOT:
+ case i_NOT:
#ifdef DISABLE_I_NOT
- failure;
+ failure;
#endif
- genamode (curi->smode, "srcreg", curi->size, "src", 1, 0);
- start_brace ();
- comprintf("\tint dst=scratchie++;\n");
- comprintf("\tmov_l_ri(dst,0xffffffff);\n");
- genflags (flag_eor, curi->size, "", "src", "dst");
- genastore ("dst", curi->smode, "srcreg", curi->size, "src");
- break;
+ genamode(curi->smode, "srcreg", curi->size, "src", GENA_GETV_FETCH, GENA_MOVEM_DO_INC);
+ start_brace();
+ comprintf("\tint dst=scratchie++;\n");
+ comprintf("\tmov_l_ri(dst,0xffffffff);\n");
+ genflags(flag_eor, curi->size, "", "src", "dst");
+ genastore("dst", curi->smode, "srcreg", curi->size, "src");
+ break;
- case i_TST:
+ case i_TST:
#ifdef DISABLE_I_TST
- failure;
+ failure;
#endif
- genamode (curi->smode, "srcreg", curi->size, "src", 1, 0);
- genflags (flag_logical, curi->size, "src", "", "");
- break;
- case i_BCHG:
- case i_BCLR:
- case i_BSET:
- case i_BTST:
+ genamode(curi->smode, "srcreg", curi->size, "src", GENA_GETV_FETCH, GENA_MOVEM_DO_INC);
+ genflags(flag_logical, curi->size, "src", "", "");
+ break;
+ case i_BCHG:
+ case i_BCLR:
+ case i_BSET:
+ case i_BTST:
#ifdef DISABLE_I_BCHG_BCLR_BSET_BTST
- failure;
+ failure;
#endif
- genamode (curi->smode, "srcreg", curi->size, "src", 1, 0);
- genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0);
- start_brace();
- comprintf("\tint s=scratchie++;\n"
- "\tint tmp=scratchie++;\n"
- "\tmov_l_rr(s,src);\n");
- if (curi->size == sz_byte)
- comprintf("\tand_l_ri(s,7);\n");
- else
- comprintf("\tand_l_ri(s,31);\n");
+ genamode(curi->smode, "srcreg", curi->size, "src", GENA_GETV_FETCH, GENA_MOVEM_DO_INC);
+ genamode(curi->dmode, "dstreg", curi->size, "dst", GENA_GETV_FETCH, GENA_MOVEM_DO_INC);
+ start_brace();
+ comprintf("\tint s=scratchie++;\n"
+ "\tint tmp=scratchie++;\n"
+ "\tmov_l_rr(s,src);\n");
+ if (curi->size == sz_byte)
+ comprintf("\tand_l_ri(s,7);\n");
+ else
+ comprintf("\tand_l_ri(s,31);\n");
- {
- const char* op;
- int need_write=1;
-
- switch(curi->mnemo) {
- case i_BCHG: op="btc"; break;
- case i_BCLR: op="btr"; break;
- case i_BSET: op="bts"; break;
- case i_BTST: op="bt"; need_write=0; break;
- default: assert(0);
- }
- comprintf("\t%s_l_rr(dst,s);\n" /* Answer now in C */
- "\tsbb_l(s,s);\n" /* s is 0 if bit was 0, -1 otherwise */
- "\tmake_flags_live();\n" /* Get the flags back */
- "\tdont_care_flags();\n",op);
- if (!noflags) {
- comprintf("\tstart_needflags();\n"
+ {
+ const char *op;
+ int need_write = 1;
+
+ switch (curi->mnemo) {
+ case i_BCHG: op = "btc"; break;
+ case i_BCLR: op = "btr"; break;
+ case i_BSET: op = "bts"; break;
+ case i_BTST: op = "bt"; need_write = 0; break;
+ default: op = ""; assert(0);
+ }
+ comprintf("\t%s_l_rr(dst,s);\n" /* Answer now in C */
+ "\tsbb_l(s,s);\n" /* s is 0 if bit was 0, -1 otherwise */
+ "\tmake_flags_live();\n" /* Get the flags back */
+ "\tdont_care_flags();\n", op);
+ if (!noflags) {
+ comprintf("\tstart_needflags();\n"
"\tset_zero(s,tmp);\n"
"\tlive_flags();\n"
"\tend_needflags();\n");
+ }
+ if (need_write)
+ genastore("dst", curi->dmode, "dstreg", curi->size, "dst");
}
- if (need_write)
- genastore ("dst", curi->dmode, "dstreg", curi->size, "dst");
- }
- break;
+ break;
- case i_CMPM:
- case i_CMP:
+ case i_CMPM:
+ case i_CMP:
#ifdef DISABLE_I_CMPM_CMP
- failure;
+ failure;
#endif
- genamode (curi->smode, "srcreg", curi->size, "src", 1, 0);
- genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0);
- start_brace ();
- genflags (flag_cmp, curi->size, "", "src", "dst");
- break;
+ genamode(curi->smode, "srcreg", curi->size, "src", GENA_GETV_FETCH, GENA_MOVEM_DO_INC);
+ genamode(curi->dmode, "dstreg", curi->size, "dst", GENA_GETV_FETCH, GENA_MOVEM_DO_INC);
+ start_brace();
+ genflags(flag_cmp, curi->size, "", "src", "dst");
+ break;
- case i_CMPA:
+ case i_CMPA:
#ifdef DISABLE_I_CMPA
- failure;
+ failure;
#endif
- genamode (curi->smode, "srcreg", curi->size, "src", 1, 0);
- genamode (curi->dmode, "dstreg", sz_long, "dst", 1, 0);
- start_brace();
- comprintf("\tint tmps=scratchie++;\n");
- switch(curi->size) {
- case sz_byte: comprintf("\tsign_extend_8_rr(tmps,src);\n"); break;
- case sz_word: comprintf("\tsign_extend_16_rr(tmps,src);\n"); break;
- case sz_long: comprintf("tmps=src;\n"); break;
- default: assert(0);
- }
- genflags (flag_cmp, sz_long, "", "tmps", "dst");
- break;
- /* The next two are coded a little unconventional, but they are doing
- * weird things... */
+ genamode(curi->smode, "srcreg", curi->size, "src", GENA_GETV_FETCH, GENA_MOVEM_DO_INC);
+ genamode(curi->dmode, "dstreg", sz_long, "dst", GENA_GETV_FETCH, GENA_MOVEM_DO_INC);
+ start_brace();
+ comprintf("\tint tmps=scratchie++;\n");
+ switch (curi->size) {
+ case sz_byte: comprintf("\tsign_extend_8_rr(tmps,src);\n"); break;
+ case sz_word: comprintf("\tsign_extend_16_rr(tmps,src);\n"); break;
+ case sz_long: comprintf("tmps=src;\n"); break;
+ default: assert(0);
+ }
+ genflags(flag_cmp, sz_long, "", "tmps", "dst");
+ break;
+ /* The next two are coded a little unconventional, but they are doing
+ * weird things... */
- case i_MVPRM:
- isjump;
- failure;
- break;
+ case i_MVPRM:
+ isjump;
+ failure;
+ break;
- case i_MVPMR:
- isjump;
- failure;
- break;
+ case i_MVPMR:
+ isjump;
+ failure;
+ break;
- case i_MOVE:
+ case i_MOVE:
#ifdef DISABLE_I_MOVE
- failure;
-#endif
- switch(curi->dmode) {
- case Dreg:
- case Areg:
- genamode (curi->smode, "srcreg", curi->size, "src", 1, 0);
- genamode (curi->dmode, "dstreg", curi->size, "dst", 2, 0);
- genflags (flag_mov, curi->size, "", "src", "dst");
- genastore ("dst", curi->dmode, "dstreg", curi->size, "dst");
- break;
- default: /* It goes to memory, not a register */
- genamode (curi->smode, "srcreg", curi->size, "src", 1, 0);
- genamode (curi->dmode, "dstreg", curi->size, "dst", 2, 0);
- genflags (flag_logical, curi->size, "src", "", "");
- genastore ("src", curi->dmode, "dstreg", curi->size, "dst");
- break;
- }
- break;
+ failure;
+#endif
+ switch (curi->dmode) {
+ case Dreg:
+ case Areg:
+ genamode(curi->smode, "srcreg", curi->size, "src", GENA_GETV_FETCH, GENA_MOVEM_DO_INC);
+ genamode(curi->dmode, "dstreg", curi->size, "dst", GENA_GETV_FETCH_ALIGN, GENA_MOVEM_DO_INC);
+ genflags(flag_mov, curi->size, "", "src", "dst");
+ genastore("dst", curi->dmode, "dstreg", curi->size, "dst");
+ break;
+ default: /* It goes to memory, not a register */
+ genamode(curi->smode, "srcreg", curi->size, "src", GENA_GETV_FETCH, GENA_MOVEM_DO_INC);
+ genamode(curi->dmode, "dstreg", curi->size, "dst", GENA_GETV_FETCH_ALIGN, GENA_MOVEM_DO_INC);
+ genflags(flag_logical, curi->size, "src", "", "");
+ genastore("src", curi->dmode, "dstreg", curi->size, "dst");
+ break;
+ }
+ break;
- case i_MOVEA:
+ case i_MOVEA:
#ifdef DISABLE_I_MOVEA
- failure;
+ failure;
#endif
- genamode (curi->smode, "srcreg", curi->size, "src", 1, 0);
- genamode (curi->dmode, "dstreg", curi->size, "dst", 2, 0);
+ genamode(curi->smode, "srcreg", curi->size, "src", GENA_GETV_FETCH, GENA_MOVEM_DO_INC);
+ genamode(curi->dmode, "dstreg", curi->size, "dst", GENA_GETV_FETCH_ALIGN, GENA_MOVEM_DO_INC);
- start_brace();
- comprintf("\tint tmps=scratchie++;\n");
- switch(curi->size) {
- case sz_word: comprintf("\tsign_extend_16_rr(dst,src);\n"); break;
- case sz_long: comprintf("\tmov_l_rr(dst,src);\n"); break;
- default: assert(0);
- }
- genastore ("dst", curi->dmode, "dstreg", sz_long, "dst");
- break;
+ start_brace();
+ comprintf("\tint tmps=scratchie++;\n");
+ switch (curi->size) {
+ case sz_word: comprintf("\tsign_extend_16_rr(dst,src);\n"); break;
+ case sz_long: comprintf("\tmov_l_rr(dst,src);\n"); break;
+ default: assert(0);
+ }
+ genastore("dst", curi->dmode, "dstreg", sz_long, "dst");
+ break;
- case i_MVSR2:
- isjump;
- failure;
- break;
+ case i_MVSR2:
+ isjump;
+ failure;
+ break;
- case i_MV2SR:
- isjump;
- failure;
- break;
+ case i_MV2SR:
+ isjump;
+ failure;
+ break;
- case i_SWAP:
+ case i_SWAP:
#ifdef DISABLE_I_SWAP
- failure;
+ failure;
#endif
- genamode (curi->smode, "srcreg", sz_long, "src", 1, 0);
- comprintf("\tdont_care_flags();\n");
- comprintf("\trol_l_ri(src,16);\n");
- genflags (flag_logical, sz_long, "src", "", "");
- genastore ("src", curi->smode, "srcreg", sz_long, "src");
- break;
+ genamode(curi->smode, "srcreg", sz_long, "src", GENA_GETV_FETCH, GENA_MOVEM_DO_INC);
+ comprintf("\tdont_care_flags();\n");
+ comprintf("\trol_l_ri(src,16);\n");
+ genflags(flag_logical, sz_long, "src", "", "");
+ genastore("src", curi->smode, "srcreg", sz_long, "src");
+ break;
- case i_EXG:
+ case i_EXG:
#ifdef DISABLE_I_EXG
- failure;
+ failure;
#endif
- genamode (curi->smode, "srcreg", curi->size, "src", 1, 0);
- genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0);
- start_brace();
- comprintf("\tint tmp=scratchie++;\n"
- "\tmov_l_rr(tmp,src);\n");
- genastore ("dst", curi->smode, "srcreg", curi->size, "src");
- genastore ("tmp", curi->dmode, "dstreg", curi->size, "dst");
- break;
+ genamode(curi->smode, "srcreg", curi->size, "src", GENA_GETV_FETCH, GENA_MOVEM_DO_INC);
+ genamode(curi->dmode, "dstreg", curi->size, "dst", GENA_GETV_FETCH, GENA_MOVEM_DO_INC);
+ start_brace();
+ comprintf("\tint tmp=scratchie++;\n"
+ "\tmov_l_rr(tmp,src);\n");
+ genastore("dst", curi->smode, "srcreg", curi->size, "src");
+ genastore("tmp", curi->dmode, "dstreg", curi->size, "dst");
+ break;
- case i_EXT:
+ case i_EXT:
#ifdef DISABLE_I_EXT
- failure;
+ failure;
#endif
- genamode (curi->smode, "srcreg", sz_long, "src", 1, 0);
- comprintf("\tdont_care_flags();\n");
- start_brace ();
- switch (curi->size)
- {
- case sz_byte:
- comprintf ("\tint dst = src;\n"
- "\tsign_extend_8_rr(src,src);\n");
- break;
- case sz_word:
- comprintf ("\tint dst = scratchie++;\n"
- "\tsign_extend_8_rr(dst,src);\n");
- break;
- case sz_long:
- comprintf ("\tint dst = src;\n"
- "\tsign_extend_16_rr(src,src);\n");
- break;
- default:
- assert(0);
- }
- genflags (flag_logical,
- curi->size == sz_word ? sz_word : sz_long, "dst", "", "");
- genastore ("dst", curi->smode, "srcreg",
- curi->size == sz_word ? sz_word : sz_long, "src");
- break;
+ genamode(curi->smode, "srcreg", sz_long, "src", GENA_GETV_FETCH, GENA_MOVEM_DO_INC);
+ comprintf("\tdont_care_flags();\n");
+ start_brace();
+ switch (curi->size)
+ {
+ case sz_byte:
+ comprintf("\tint dst = src;\n"
+ "\tsign_extend_8_rr(src,src);\n");
+ break;
+ case sz_word:
+ comprintf("\tint dst = scratchie++;\n"
+ "\tsign_extend_8_rr(dst,src);\n");
+ break;
+ case sz_long:
+ comprintf("\tint dst = src;\n"
+ "\tsign_extend_16_rr(src,src);\n");
+ break;
+ default:
+ assert(0);
+ }
+ genflags(flag_logical,
+ curi->size == sz_word ? sz_word : sz_long, "dst", "", "");
+ genastore("dst", curi->smode, "srcreg",
+ curi->size == sz_word ? sz_word : sz_long, "src");
+ break;
- case i_MVMEL:
+ case i_MVMEL:
#ifdef DISABLE_I_MVEL
- failure;
+ failure;
#endif
- genmovemel (opcode);
- break;
+ genmovemel(opcode);
+ break;
- case i_MVMLE:
+ case i_MVMLE:
#ifdef DISABLE_I_MVMLE
- failure;
+ failure;
#endif
- genmovemle (opcode);
- break;
+ genmovemle(opcode);
+ break;
- case i_TRAP:
- isjump;
- failure;
- break;
+ case i_TRAP:
+#ifdef DISABLE_I_TRAP
+ failure;
+#endif
+ isjump;
+ mayfail;
+ start_brace();
+ comprintf(" int trapno = srcreg + 32;\n");
+ gen_set_fault_pc();
+ make_sr();
+ comprintf(" compemu_enter_super(sr);\n");
+ comprintf(" compemu_exc_make_frame(0, sr, ret, trapno, scratchie);\n");
+ comprintf(" forget_about(ret);\n");
+ /* m68k_setpc (get_long (regs.vbr + 4*nr)); */
+ start_brace();
+ comprintf(" int srca = scratchie++;\n");
+ comprintf(" mov_l_rm(srca, (uintptr)®s.vbr);\n");
+ comprintf(" mov_l_brR(srca, srca, MEMBaseDiff + trapno * 4); mid_bswap_32(srca);\n");
+ comprintf(" mov_l_mr((uintptr)®s.pc, srca);\n");
+ comprintf(" get_n_addr_jmp(srca, PC_P, scratchie);\n");
+ comprintf(" mov_l_mr((uintptr)®s.pc_oldp, PC_P);\n");
+ gen_update_next_handler();
+ disasm_this_inst(); /* for debugging only */
+ /*
+ * this currently deactivates this feature, since it does not work yet
+ */
+ failure;
+ break;
- case i_MVR2USP:
- isjump;
- failure;
- break;
+ case i_MVR2USP:
+ isjump;
+ failure;
+ break;
- case i_MVUSP2R:
- isjump;
- failure;
- break;
+ case i_MVUSP2R:
+ isjump;
+ failure;
+ break;
- case i_RESET:
- isjump;
- failure;
- break;
+ case i_RESET:
+ isjump;
+ failure;
+ break;
- case i_NOP:
- break;
+ case i_NOP:
+ break;
- case i_STOP:
- isjump;
- failure;
- break;
+ case i_STOP:
+ isjump;
+ failure;
+ break;
- case i_RTE:
- isjump;
- failure;
- break;
+ case i_RTE:
+ isjump;
+ failure;
+ break;
- case i_RTD:
+ case i_RTD:
#ifdef DISABLE_I_RTD
- failure;
+ failure;
#endif
- genamode (curi->smode, "srcreg", curi->size, "offs", 1, 0);
- /* offs is constant */
- comprintf("\tadd_l_ri(offs,4);\n");
- start_brace();
- comprintf("\tint newad=scratchie++;\n"
- "\treadlong(15,newad,scratchie);\n"
- "\tmov_l_mr((uintptr)®s.pc,newad);\n"
- "\tget_n_addr_jmp(newad,PC_P,scratchie);\n"
- "\tmov_l_mr((uintptr)®s.pc_oldp,PC_P);\n"
- "\tm68k_pc_offset=0;\n"
- "\tadd_l(15,offs);\n");
- gen_update_next_handler();
- isjump;
- break;
+ genamode(curi->smode, "srcreg", curi->size, "offs", GENA_GETV_FETCH, GENA_MOVEM_DO_INC);
+ /* offs is constant */
+ comprintf("\tadd_l_ri(offs,4);\n");
+ start_brace();
+ comprintf("\tint newad=scratchie++;\n"
+ "\treadlong(SP_REG,newad,scratchie);\n"
+ "\tmov_l_mr((uintptr)®s.pc,newad);\n"
+ "\tget_n_addr_jmp(newad,PC_P,scratchie);\n"
+ "\tmov_l_mr((uintptr)®s.pc_oldp,PC_P);\n"
+ "\tm68k_pc_offset=0;\n"
+ "\tadd_l(SP_REG,offs);\n");
+ gen_update_next_handler();
+ isjump;
+ break;
- case i_LINK:
+ case i_LINK:
#ifdef DISABLE_I_LINK
- failure;
-#endif
- genamode (curi->smode, "srcreg", sz_long, "src", 1, 0);
- genamode (curi->dmode, "dstreg", curi->size, "offs", 1, 0);
- comprintf("\tsub_l_ri(15,4);\n"
- "\twritelong_clobber(15,src,scratchie);\n"
- "\tmov_l_rr(src,15);\n");
- if (curi->size==sz_word)
- comprintf("\tsign_extend_16_rr(offs,offs);\n");
- comprintf("\tadd_l(15,offs);\n");
- genastore ("src", curi->smode, "srcreg", sz_long, "src");
- break;
+ failure;
+#endif
+ genamode(curi->smode, "srcreg", sz_long, "src", GENA_GETV_FETCH, GENA_MOVEM_DO_INC);
+ genamode(curi->dmode, "dstreg", curi->size, "offs", GENA_GETV_FETCH, GENA_MOVEM_DO_INC);
+ comprintf("\tsub_l_ri(SP_REG,4);\n"
+ "\twritelong_clobber(SP_REG,src,scratchie);\n"
+ "\tmov_l_rr(src,SP_REG);\n");
+ if (curi->size == sz_word)
+ comprintf("\tsign_extend_16_rr(offs,offs);\n");
+ comprintf("\tadd_l(SP_REG,offs);\n");
+ genastore("src", curi->smode, "srcreg", sz_long, "src");
+ break;
- case i_UNLK:
+ case i_UNLK:
#ifdef DISABLE_I_UNLK
- failure;
+ failure;
#endif
- genamode (curi->smode, "srcreg", curi->size, "src", 1, 0);
- comprintf("\tmov_l_rr(15,src);\n"
- "\treadlong(15,src,scratchie);\n"
- "\tadd_l_ri(15,4);\n");
- genastore ("src", curi->smode, "srcreg", curi->size, "src");
- break;
+ genamode(curi->smode, "srcreg", curi->size, "src", GENA_GETV_FETCH, GENA_MOVEM_DO_INC);
+ comprintf("\tmov_l_rr(SP_REG,src);\n"
+ "\treadlong(SP_REG,src,scratchie);\n"
+ "\tadd_l_ri(SP_REG,4);\n");
+ genastore("src", curi->smode, "srcreg", curi->size, "src");
+ break;
- case i_RTS:
+ case i_RTS:
#ifdef DISABLE_I_RTS
- failure;
-#endif
- comprintf("\tint newad=scratchie++;\n"
- "\treadlong(15,newad,scratchie);\n"
- "\tmov_l_mr((uintptr)®s.pc,newad);\n"
- "\tget_n_addr_jmp(newad,PC_P,scratchie);\n"
- "\tmov_l_mr((uintptr)®s.pc_oldp,PC_P);\n"
- "\tm68k_pc_offset=0;\n"
- "\tlea_l_brr(15,15,4);\n");
- gen_update_next_handler();
- isjump;
- break;
+ failure;
+#endif
+ comprintf("\tint newad=scratchie++;\n"
+ "\treadlong(SP_REG,newad,scratchie);\n"
+ "\tmov_l_mr((uintptr)®s.pc,newad);\n"
+ "\tget_n_addr_jmp(newad,PC_P,scratchie);\n"
+ "\tmov_l_mr((uintptr)®s.pc_oldp,PC_P);\n"
+ "\tm68k_pc_offset=0;\n"
+ "\tlea_l_brr(SP_REG,SP_REG,4);\n");
+ gen_update_next_handler();
+ isjump;
+ break;
- case i_TRAPV:
- isjump;
- failure;
- break;
+ case i_TRAPV:
+ isjump;
+ failure;
+ break;
- case i_RTR:
- isjump;
- failure;
- break;
+ case i_RTR:
+ isjump;
+ failure;
+ break;
- case i_JSR:
+ case i_JSR:
#ifdef DISABLE_I_JSR
- failure;
+ failure;
#endif
- isjump;
- genamode (curi->smode, "srcreg", curi->size, "src", 0, 0);
- start_brace();
- comprintf("\tuae_u32 retadd=start_pc+((char *)comp_pc_p-(char *)start_pc_p)+m68k_pc_offset;\n");
- comprintf("\tint ret=scratchie++;\n"
- "\tmov_l_ri(ret,retadd);\n"
- "\tsub_l_ri(15,4);\n"
- "\twritelong_clobber(15,ret,scratchie);\n");
- comprintf("\tmov_l_mr((uintptr)®s.pc,srca);\n"
- "\tget_n_addr_jmp(srca,PC_P,scratchie);\n"
- "\tmov_l_mr((uintptr)®s.pc_oldp,PC_P);\n"
- "\tm68k_pc_offset=0;\n");
- gen_update_next_handler();
- break;
+ isjump;
+ genamode(curi->smode, "srcreg", curi->size, "src", GENA_GETV_NO_FETCH, GENA_MOVEM_DO_INC);
+ start_brace();
+ comprintf("\tuae_u32 retadd=start_pc+((char *)comp_pc_p-(char *)start_pc_p)+m68k_pc_offset;\n");
+ comprintf("\tint ret=scratchie++;\n"
+ "\tmov_l_ri(ret,retadd);\n"
+ "\tsub_l_ri(SP_REG,4);\n"
+ "\twritelong_clobber(SP_REG,ret,scratchie);\n");
+ comprintf("\tmov_l_mr((uintptr)®s.pc,srca);\n"
+ "\tget_n_addr_jmp(srca,PC_P,scratchie);\n"
+ "\tmov_l_mr((uintptr)®s.pc_oldp,PC_P);\n"
+ "\tm68k_pc_offset=0;\n");
+ gen_update_next_handler();
+ break;
- case i_JMP:
+ case i_JMP:
#ifdef DISABLE_I_JMP
- failure;
-#endif
- isjump;
- genamode (curi->smode, "srcreg", curi->size, "src", 0, 0);
- comprintf("\tmov_l_mr((uintptr)®s.pc,srca);\n"
- "\tget_n_addr_jmp(srca,PC_P,scratchie);\n"
- "\tmov_l_mr((uintptr)®s.pc_oldp,PC_P);\n"
- "\tm68k_pc_offset=0;\n");
- gen_update_next_handler();
- break;
+ failure;
+#endif
+ isjump;
+ genamode(curi->smode, "srcreg", curi->size, "src", GENA_GETV_NO_FETCH, GENA_MOVEM_DO_INC);
+ comprintf("\tmov_l_mr((uintptr)®s.pc,srca);\n"
+ "\tget_n_addr_jmp(srca,PC_P,scratchie);\n"
+ "\tmov_l_mr((uintptr)®s.pc_oldp,PC_P);\n"
+ "\tm68k_pc_offset=0;\n");
+ gen_update_next_handler();
+ break;
- case i_BSR:
+ case i_BSR:
#ifdef DISABLE_I_BSR
- failure;
+ failure;
#endif
- is_const_jump;
- genamode (curi->smode, "srcreg", curi->size, "src", 1, 0);
- start_brace();
- comprintf("\tuae_u32 retadd=start_pc+((char *)comp_pc_p-(char *)start_pc_p)+m68k_pc_offset;\n");
- comprintf("\tint ret=scratchie++;\n"
- "\tmov_l_ri(ret,retadd);\n"
- "\tsub_l_ri(15,4);\n"
- "\twritelong_clobber(15,ret,scratchie);\n");
- comprintf("\tadd_l_ri(src,m68k_pc_offset_thisinst+2);\n");
- comprintf("\tm68k_pc_offset=0;\n");
- comprintf("\tadd_l(PC_P,src);\n");
-
- comprintf("\tcomp_pc_p=(uae_u8*)(uintptr)get_const(PC_P);\n");
- break;
+ is_const_jump;
+ genamode(curi->smode, "srcreg", curi->size, "src", GENA_GETV_FETCH, GENA_MOVEM_DO_INC);
+ start_brace();
+ comprintf("\tuae_u32 retadd=start_pc+((char *)comp_pc_p-(char *)start_pc_p)+m68k_pc_offset;\n");
+ comprintf("\tint ret=scratchie++;\n"
+ "\tmov_l_ri(ret,retadd);\n"
+ "\tsub_l_ri(SP_REG,4);\n"
+ "\twritelong_clobber(SP_REG,ret,scratchie);\n");
+ comprintf("\tadd_l_ri(src,m68k_pc_offset_thisinst+2);\n");
+ comprintf("\tm68k_pc_offset=0;\n");
+ comprintf("\tadd_l(PC_P,src);\n");
+
+ comprintf("\tcomp_pc_p=(uae_u8*)(uintptr)get_const(PC_P);\n");
+ gen_update_next_handler();
+ break;
- case i_Bcc:
+ case i_Bcc:
#ifdef DISABLE_I_BCC
- failure;
-#endif
- comprintf("\tuae_u32 v,v1,v2;\n");
- genamode (curi->smode, "srcreg", curi->size, "src", 1, 0);
- /* That source is an immediate, so we can clobber it with abandon */
- switch(curi->size) {
- case sz_byte: comprintf("\tsign_extend_8_rr(src,src);\n"); break;
- case sz_word: comprintf("\tsign_extend_16_rr(src,src);\n"); break;
- case sz_long: break;
- }
- comprintf("\tsub_l_ri(src,m68k_pc_offset-m68k_pc_offset_thisinst-2);\n");
- /* Leave the following as "add" --- it will allow it to be optimized
- away due to src being a constant ;-) */
- comprintf("\tadd_l_ri(src,(uintptr)comp_pc_p);\n");
- comprintf("\tmov_l_ri(PC_P,(uintptr)comp_pc_p);\n");
- /* Now they are both constant. Might as well fold in m68k_pc_offset */
- comprintf("\tadd_l_ri(src,m68k_pc_offset);\n");
- comprintf("\tadd_l_ri(PC_P,m68k_pc_offset);\n");
- comprintf("\tm68k_pc_offset=0;\n");
-
- if (curi->cc>=2) {
- comprintf("\tv1=get_const(PC_P);\n"
- "\tv2=get_const(src);\n"
- "\tregister_branch(v1,v2,%d);\n",
- cond_codes[curi->cc]);
- comprintf("\tmake_flags_live();\n"); /* Load the flags */
- isjump;
- }
- else {
- is_const_jump;
- }
+ failure;
+#endif
+ comprintf("\tuae_u32 v,v1,v2;\n");
+ genamode(curi->smode, "srcreg", curi->size, "src", GENA_GETV_FETCH, GENA_MOVEM_DO_INC);
+ /* That source is an immediate, so we can clobber it with abandon */
+ switch (curi->size) {
+ case sz_byte: comprintf("\tsign_extend_8_rr(src,src);\n"); break;
+ case sz_word: comprintf("\tsign_extend_16_rr(src,src);\n"); break;
+ case sz_long: break;
+ }
+ comprintf("\tsub_l_ri(src,m68k_pc_offset-m68k_pc_offset_thisinst-2);\n");
+ /* Leave the following as "add" --- it will allow it to be optimized
+ away due to src being a constant ;-) */
+ comprintf("\tadd_l_ri(src,(uintptr)comp_pc_p);\n");
+ comprintf("\tmov_l_ri(PC_P,(uintptr)comp_pc_p);\n");
+ /* Now they are both constant. Might as well fold in m68k_pc_offset */
+ comprintf("\tadd_l_ri(src,m68k_pc_offset);\n");
+ comprintf("\tadd_l_ri(PC_P,m68k_pc_offset);\n");
+ comprintf("\tm68k_pc_offset=0;\n");
+
+ if (curi->cc >= 2) {
+ comprintf("\tv1=get_const(PC_P);\n"
+ "\tv2=get_const(src);\n"
+ "\tregister_branch(v1,v2,%d);\n",
+ cond_codes[curi->cc]);
+ comprintf("\tmake_flags_live();\n"); /* Load the flags */
+ isjump;
+ } else {
+ is_const_jump;
+ }
- switch(curi->cc) {
- case 0: /* Unconditional jump */
- comprintf("\tmov_l_rr(PC_P,src);\n");
- comprintf("\tcomp_pc_p=(uae_u8*)(uintptr)get_const(PC_P);\n");
- break;
- case 1: break; /* This is silly! */
- case 8: failure; break; /* Work out details! FIXME */
- case 9: failure; break; /* Not critical, though! */
-
- case 2:
- case 3:
- case 4:
- case 5:
- case 6:
- case 7:
- case 10:
- case 11:
- case 12:
- case 13:
- case 14:
- case 15:
- break;
- default: assert(0);
- }
- break;
+ switch (curi->cc) {
+ case 0: /* Unconditional jump */
+ comprintf("\tmov_l_rr(PC_P,src);\n");
+ comprintf("\tcomp_pc_p=(uae_u8*)(uintptr)get_const(PC_P);\n");
+ break;
+ case 1: break; /* This is silly! */
+ case 8: failure; break; /* Work out details! FIXME */
+ case 9: failure; break; /* Not critical, though! */
+
+ case 2:
+ case 3:
+ case 4:
+ case 5:
+ case 6:
+ case 7:
+ case 10:
+ case 11:
+ case 12:
+ case 13:
+ case 14:
+ case 15:
+ break;
+ default: assert(0);
+ }
+ break;
- case i_LEA:
+ case i_LEA:
#ifdef DISABLE_I_LEA
- failure;
+ failure;
#endif
- genamode (curi->smode, "srcreg", curi->size, "src", 0, 0);
- genamode (curi->dmode, "dstreg", curi->size, "dst", 2, 0);
- genastore ("srca", curi->dmode, "dstreg", curi->size, "dst");
- break;
+ genamode(curi->smode, "srcreg", curi->size, "src", GENA_GETV_NO_FETCH, GENA_MOVEM_DO_INC);
+ genamode(curi->dmode, "dstreg", curi->size, "dst", GENA_GETV_FETCH_ALIGN, GENA_MOVEM_DO_INC);
+ genastore("srca", curi->dmode, "dstreg", curi->size, "dst");
+ break;
- case i_PEA:
+ case i_PEA:
#ifdef DISABLE_I_PEA
- failure;
-#endif
- if (table68k[opcode].smode==Areg ||
- table68k[opcode].smode==Aind ||
- table68k[opcode].smode==Aipi ||
- table68k[opcode].smode==Apdi ||
- table68k[opcode].smode==Ad16 ||
- table68k[opcode].smode==Ad8r)
- comprintf("if (srcreg==7) dodgy=1;\n");
-
- genamode (curi->smode, "srcreg", curi->size, "src", 0, 0);
- genamode (Apdi, "7", sz_long, "dst", 2, 0);
- genastore ("srca", Apdi, "7", sz_long, "dst");
- break;
+ failure;
+#endif
+ if (table68k[opcode].smode == Areg ||
+ table68k[opcode].smode == Aind ||
+ table68k[opcode].smode == Aipi ||
+ table68k[opcode].smode == Apdi ||
+ table68k[opcode].smode == Ad16 ||
+ table68k[opcode].smode == Ad8r)
+ comprintf("if (srcreg==7) dodgy=1;\n");
+
+ genamode(curi->smode, "srcreg", curi->size, "src", GENA_GETV_NO_FETCH, GENA_MOVEM_DO_INC);
+ genamode(Apdi, "7", sz_long, "dst", GENA_GETV_FETCH_ALIGN, GENA_MOVEM_DO_INC);
+ genastore("srca", Apdi, "7", sz_long, "dst");
+ break;
- case i_DBcc:
+ case i_DBcc:
#ifdef DISABLE_I_DBCC
- failure;
+ failure;
#endif
- isjump;
- uses_cmov;
- genamode (curi->smode, "srcreg", curi->size, "src", 1, 0);
- genamode (curi->dmode, "dstreg", curi->size, "offs", 1, 0);
+ isjump;
+ uses_cmov;
+ genamode(curi->smode, "srcreg", curi->size, "src", GENA_GETV_FETCH, GENA_MOVEM_DO_INC);
+ genamode(curi->dmode, "dstreg", curi->size, "offs", GENA_GETV_FETCH, GENA_MOVEM_DO_INC);
- /* That offs is an immediate, so we can clobber it with abandon */
- switch(curi->size) {
- case sz_word: comprintf("\tsign_extend_16_rr(offs,offs);\n"); break;
- default: assert(0); /* Seems this only comes in word flavour */
- }
- comprintf("\tsub_l_ri(offs,m68k_pc_offset-m68k_pc_offset_thisinst-2);\n");
- comprintf("\tadd_l_ri(offs,(uintptr)comp_pc_p);\n"); /* New PC,
- once the
- offset_68k is
- * also added */
- /* Let's fold in the m68k_pc_offset at this point */
- comprintf("\tadd_l_ri(offs,m68k_pc_offset);\n");
- comprintf("\tadd_l_ri(PC_P,m68k_pc_offset);\n");
- comprintf("\tm68k_pc_offset=0;\n");
+ /* That offs is an immediate, so we can clobber it with abandon */
+ switch (curi->size) {
+ case sz_word: comprintf("\tsign_extend_16_rr(offs,offs);\n"); break;
+ default: assert(0); /* Seems this only comes in word flavour */
+ }
+ comprintf("\tsub_l_ri(offs,m68k_pc_offset-m68k_pc_offset_thisinst-2);\n");
+ comprintf("\tadd_l_ri(offs,(uintptr)comp_pc_p);\n"); /* New PC,
+ once the
+ offset_68k is
+ * also added */
+ /* Let's fold in the m68k_pc_offset at this point */
+ comprintf("\tadd_l_ri(offs,m68k_pc_offset);\n");
+ comprintf("\tadd_l_ri(PC_P,m68k_pc_offset);\n");
+ comprintf("\tm68k_pc_offset=0;\n");
- start_brace();
- comprintf("\tint nsrc=scratchie++;\n");
+ start_brace();
+ comprintf("\tint nsrc=scratchie++;\n");
- if (curi->cc>=2) {
- comprintf("\tmake_flags_live();\n"); /* Load the flags */
- }
+ if (curi->cc >= 2) {
+ comprintf("\tmake_flags_live();\n"); /* Load the flags */
+ }
- assert (curi->size==sz_word);
-
- switch(curi->cc) {
- case 0: /* This is an elaborate nop? */
- break;
- case 1:
- comprintf("\tstart_needflags();\n");
- comprintf("\tsub_w_ri(src,1);\n");
- comprintf("\t end_needflags();\n");
- start_brace();
- comprintf("\tuae_u32 v2,v;\n"
- "\tuae_u32 v1=get_const(PC_P);\n");
- comprintf("\tv2=get_const(offs);\n"
- "\tregister_branch(v1,v2,%d);\n", NATIVE_CC_CC);
- break;
-
- case 8: failure; break; /* Work out details! FIXME */
- case 9: failure; break; /* Not critical, though! */
-
- case 2:
- case 3:
- case 4:
- case 5:
- case 6:
- case 7:
- case 10:
- case 11:
- case 12:
- case 13:
- case 14:
- case 15:
- comprintf("\tmov_l_rr(nsrc,src);\n");
- comprintf("\tlea_l_brr(scratchie,src,(uae_s32)-1);\n"
- "\tmov_w_rr(src,scratchie);\n");
- comprintf("\tcmov_l_rr(offs,PC_P,%d);\n",
- cond_codes[curi->cc]);
- comprintf("\tcmov_l_rr(src,nsrc,%d);\n",
- cond_codes[curi->cc]);
- /* OK, now for cc=true, we have src==nsrc and offs==PC_P,
- so whether we move them around doesn't matter. However,
- if cc=false, we have offs==jump_pc, and src==nsrc-1 */
-
- comprintf("\t start_needflags();\n");
- comprintf("\ttest_w_rr(nsrc,nsrc);\n");
- comprintf("\t end_needflags();\n");
- comprintf("\tcmov_l_rr(PC_P,offs,%d);\n", NATIVE_CC_NE);
- break;
- default: assert(0);
- }
- genastore ("src", curi->smode, "srcreg", curi->size, "src");
- gen_update_next_handler();
- break;
+ assert(curi->size == sz_word);
+
+ switch (curi->cc) {
+ case 0: /* This is an elaborate nop? */
+ break;
+ case 1:
+ comprintf("\tstart_needflags();\n");
+ comprintf("\tsub_w_ri(src,1);\n");
+ comprintf("\tend_needflags();\n");
+ start_brace();
+ comprintf("\tuae_u32 v2,v;\n"
+ "\tuae_u32 v1=get_const(PC_P);\n");
+ comprintf("\tv2=get_const(offs);\n"
+ "\tregister_branch(v1,v2,%d);\n", NATIVE_CC_CC);
+ break;
+
+ case 8: failure; break; /* Work out details! FIXME */
+ case 9: failure; break; /* Not critical, though! */
+
+ case 2:
+ case 3:
+ case 4:
+ case 5:
+ case 6:
+ case 7:
+ case 10:
+ case 11:
+ case 12:
+ case 13:
+ case 14:
+ case 15:
+ comprintf("\tmov_l_rr(nsrc,src);\n");
+ comprintf("\tlea_l_brr(scratchie,src,(uae_s32)-1);\n"
+ "\tmov_w_rr(src,scratchie);\n");
+ comprintf("\tcmov_l_rr(offs,PC_P,%d);\n",
+ cond_codes[curi->cc]);
+ comprintf("\tcmov_l_rr(src,nsrc,%d);\n",
+ cond_codes[curi->cc]);
+ /* OK, now for cc=true, we have src==nsrc and offs==PC_P,
+ so whether we move them around doesn't matter. However,
+ if cc=false, we have offs==jump_pc, and src==nsrc-1 */
+
+ comprintf("\tstart_needflags();\n");
+ comprintf("\ttest_w_rr(nsrc,nsrc);\n");
+ comprintf("\tend_needflags();\n");
+ comprintf("\tcmov_l_rr(PC_P,offs,%d);\n", NATIVE_CC_NE);
+ break;
+ default: assert(0);
+ }
+ genastore("src", curi->smode, "srcreg", curi->size, "src");
+ gen_update_next_handler();
+ break;
- case i_Scc:
+ case i_Scc:
#ifdef DISABLE_I_SCC
- failure;
-#endif
- genamode (curi->smode, "srcreg", curi->size, "src", 2, 0);
- start_brace ();
- comprintf ("\tint val = scratchie++;\n");
-
- /* We set val to 0 if we really should use 255, and to 1 for real 0 */
- switch(curi->cc) {
- case 0: /* Unconditional set */
- comprintf("\tmov_l_ri(val,0);\n");
- break;
- case 1:
- /* Unconditional not-set */
- comprintf("\tmov_l_ri(val,1);\n");
- break;
- case 8: failure; break; /* Work out details! FIXME */
- case 9: failure; break; /* Not critical, though! */
-
- case 2:
- case 3:
- case 4:
- case 5:
- case 6:
- case 7:
- case 10:
- case 11:
- case 12:
- case 13:
- case 14:
- case 15:
- comprintf("\tmake_flags_live();\n"); /* Load the flags */
- /* All condition codes can be inverted by changing the LSB */
- comprintf("\tsetcc(val,%d);\n",
- cond_codes[curi->cc]^1); break;
- default: assert(0);
- }
- comprintf("\tsub_b_ri(val,1);\n");
- genastore ("val", curi->smode, "srcreg", curi->size, "src");
- break;
+ failure;
+#endif
+ genamode(curi->smode, "srcreg", curi->size, "src", GENA_GETV_FETCH_ALIGN, GENA_MOVEM_DO_INC);
+ start_brace();
+ comprintf("\tint val = scratchie++;\n");
- case i_DIVU:
- isjump;
- failure;
- break;
+ /* We set val to 0 if we really should use 255, and to 1 for real 0 */
+ switch (curi->cc) {
+ case 0: /* Unconditional set */
+ comprintf("\tmov_l_ri(val,0);\n");
+ break;
+ case 1:
+ /* Unconditional not-set */
+ comprintf("\tmov_l_ri(val,1);\n");
+ break;
+ case 8: failure; break; /* Work out details! FIXME */
+ case 9: failure; break; /* Not critical, though! */
+
+ case 2:
+ case 3:
+ case 4:
+ case 5:
+ case 6:
+ case 7:
+ case 10:
+ case 11:
+ case 12:
+ case 13:
+ case 14:
+ case 15:
+ comprintf("\tmake_flags_live();\n"); /* Load the flags */
+ /* All condition codes can be inverted by changing the LSB */
+ comprintf("\tsetcc(val,%d);\n",
+ cond_codes[curi->cc] ^ 1); break;
+ default: assert(0);
+ }
+ comprintf("\tsub_b_ri(val,1);\n");
+ genastore("val", curi->smode, "srcreg", curi->size, "src");
+ break;
- case i_DIVS:
- isjump;
- failure;
- break;
+ case i_DIVU:
+ isjump;
+ failure;
+ break;
+
+ case i_DIVS:
+ isjump;
+ failure;
+ break;
- case i_MULU:
+ case i_MULU:
#ifdef DISABLE_I_MULU
- failure;
-#endif
- comprintf("\tdont_care_flags();\n");
- genamode (curi->smode, "srcreg", sz_word, "src", 1, 0);
- genamode (curi->dmode, "dstreg", sz_word, "dst", 1, 0);
- /* To do 16x16 unsigned multiplication, we actually use
- 32x32 signed, and zero-extend the registers first.
- That solves the problem of MUL needing dedicated registers
- on the x86 */
- comprintf("\tzero_extend_16_rr(scratchie,src);\n"
- "\tzero_extend_16_rr(dst,dst);\n"
- "\timul_32_32(dst,scratchie);\n");
- genflags (flag_logical, sz_long, "dst", "", "");
- genastore ("dst", curi->dmode, "dstreg", sz_long, "dst");
- break;
+ failure;
+#endif
+ comprintf("\tdont_care_flags();\n");
+ genamode(curi->smode, "srcreg", sz_word, "src", GENA_GETV_FETCH, GENA_MOVEM_DO_INC);
+ genamode(curi->dmode, "dstreg", sz_word, "dst", GENA_GETV_FETCH, GENA_MOVEM_DO_INC);
+ /* To do 16x16 unsigned multiplication, we actually use
+ 32x32 signed, and zero-extend the registers first.
+ That solves the problem of MUL needing dedicated registers
+ on the x86 */
+ comprintf("\tzero_extend_16_rr(scratchie,src);\n"
+ "\tzero_extend_16_rr(dst,dst);\n"
+ "\timul_32_32(dst,scratchie);\n");
+ genflags(flag_logical, sz_long, "dst", "", "");
+ genastore("dst", curi->dmode, "dstreg", sz_long, "dst");
+ break;
- case i_MULS:
+ case i_MULS:
#ifdef DISABLE_I_MULS
- failure;
-#endif
- comprintf("\tdont_care_flags();\n");
- genamode (curi->smode, "srcreg", sz_word, "src", 1, 0);
- genamode (curi->dmode, "dstreg", sz_word, "dst", 1, 0);
- comprintf("\tsign_extend_16_rr(scratchie,src);\n"
- "\tsign_extend_16_rr(dst,dst);\n"
- "\timul_32_32(dst,scratchie);\n");
- genflags (flag_logical, sz_long, "dst", "", "");
- genastore ("dst", curi->dmode, "dstreg", sz_long, "dst");
- break;
+ failure;
+#endif
+ comprintf("\tdont_care_flags();\n");
+ genamode(curi->smode, "srcreg", sz_word, "src", GENA_GETV_FETCH, GENA_MOVEM_DO_INC);
+ genamode(curi->dmode, "dstreg", sz_word, "dst", GENA_GETV_FETCH, GENA_MOVEM_DO_INC);
+ comprintf("\tsign_extend_16_rr(scratchie,src);\n"
+ "\tsign_extend_16_rr(dst,dst);\n"
+ "\timul_32_32(dst,scratchie);\n");
+ genflags(flag_logical, sz_long, "dst", "", "");
+ genastore("dst", curi->dmode, "dstreg", sz_long, "dst");
+ break;
- case i_CHK:
- isjump;
- failure;
- break;
+ case i_CHK:
+ isjump;
+ failure;
+ break;
- case i_CHK2:
- isjump;
- failure;
- break;
+ case i_CHK2:
+ isjump;
+ failure;
+ break;
+
+ case i_ASR:
+#ifdef DISABLE_I_ASR
+ failure;
+#endif
+ mayfail;
+ if (curi->smode == Dreg) {
+ comprintf(
+ " if ((uae_u32)srcreg==(uae_u32)dstreg) {\n"
+ " FAIL(1);\n"
+ " " RETURN "\n"
+ " }\n");
+ start_brace();
+ }
+ comprintf("\tdont_care_flags();\n");
- case i_ASR:
-#ifdef DISABLE_I_ASR
- failure;
-#endif
- mayfail;
- if (curi->smode==Dreg) {
- comprintf("if ((uae_u32)srcreg==(uae_u32)dstreg) {\n"
- " FAIL(1);\n"
- " " RETURN "\n"
- "} \n");
- start_brace();
- }
- comprintf("\tdont_care_flags();\n");
+ genamode(curi->smode, "srcreg", curi->size, "cnt", GENA_GETV_FETCH, GENA_MOVEM_DO_INC);
+ genamode(curi->dmode, "dstreg", curi->size, "data", GENA_GETV_FETCH, GENA_MOVEM_DO_INC);
- genamode (curi->smode, "srcreg", curi->size, "cnt", 1, 0);
- genamode (curi->dmode, "dstreg", curi->size, "data", 1, 0);
- if (curi->smode!=immi) {
- if (!noflags) {
- uses_cmov;
start_brace();
- comprintf("\tint highmask;\n"
- "\tint width;\n"
- "\tint cdata=scratchie++;\n"
- "\tint tmpcnt=scratchie++;\n"
- "\tint highshift=scratchie++;\n");
- comprintf("\tmov_l_rr(tmpcnt,cnt);\n"
- "\tand_l_ri(tmpcnt,63);\n"
- "\tmov_l_ri(cdata,0);\n"
- "\tcmov_l_rr(cdata,data,%d);\n", NATIVE_CC_NE);
- /* cdata is now either data (for shift count!=0) or
- 0 (for shift count==0) */
- switch(curi->size) {
- case sz_byte: comprintf("\tshra_b_rr(data,cnt);\n"
- "\thighmask=0x38;\n"
- "\twidth=8;\n");
- break;
- case sz_word: comprintf("\tshra_w_rr(data,cnt);\n"
- "\thighmask=0x30;\n"
- "\twidth=16;\n");
- break;
- case sz_long: comprintf("\tshra_l_rr(data,cnt);\n"
- "\thighmask=0x20;\n"
- "\twidth=32;\n");
- break;
- default: assert(0);
- }
- comprintf("test_l_ri(cnt,highmask);\n"
- "mov_l_ri(highshift,0);\n"
- "mov_l_ri(scratchie,width/2);\n"
- "cmov_l_rr(highshift,scratchie,%d);\n", NATIVE_CC_NE);
- /* The x86 masks out bits, so we now make sure that things
- really get shifted as much as planned */
- switch(curi->size) {
- case sz_byte: comprintf("\tshra_b_rr(data,highshift);\n");break;
- case sz_word: comprintf("\tshra_w_rr(data,highshift);\n");break;
- case sz_long: comprintf("\tshra_l_rr(data,highshift);\n");break;
- default: assert(0);
- }
- /* And again */
- switch(curi->size) {
- case sz_byte: comprintf("\tshra_b_rr(data,highshift);\n");break;
- case sz_word: comprintf("\tshra_w_rr(data,highshift);\n");break;
- case sz_long: comprintf("\tshra_l_rr(data,highshift);\n");break;
- default: assert(0);
- }
-
- /* Result of shift is now in data. Now we need to determine
- the carry by shifting cdata one less */
- comprintf("\tsub_l_ri(tmpcnt,1);\n");
- switch(curi->size) {
- case sz_byte: comprintf("\tshra_b_rr(cdata,tmpcnt);\n");break;
- case sz_word: comprintf("\tshra_w_rr(cdata,tmpcnt);\n");break;
- case sz_long: comprintf("\tshra_l_rr(cdata,tmpcnt);\n");break;
- default: assert(0);
- }
- /* If the shift count was higher than the width, we need
- to pick up the sign from data */
- comprintf("test_l_ri(tmpcnt,highmask);\n"
- "cmov_l_rr(cdata,data,%d);\n", NATIVE_CC_NE);
+ if (!noflags)
+ comprintf("\tstart_needflags();\n");
+ if (curi->smode != immi) {
+ uses_cmov;
+ start_brace();
+ comprintf("\tint zero = scratchie++;\n");
+ comprintf("\tint tmpcnt = scratchie++;\n");
+ comprintf("\tint minus1 = scratchie++;\n");
+ comprintf("\tint cdata = minus1;\n");
+ comprintf("\tmov_l_rr(tmpcnt,cnt);\n");
+ comprintf("\tand_l_ri(tmpcnt,63);\n");
+ comprintf("\tmov_l_ri(zero, 0);\n");
+ comprintf("\tmov_l_ri(minus1, -1);\n");
+ switch (curi->size) {
+ case sz_byte:
+ comprintf("\ttest_b_rr(data,data);\n");
+ comprintf("\tcmov_l_rr(zero, minus1, NATIVE_CC_MI);\n");
+ comprintf("\ttest_l_ri(tmpcnt, 0x38);\n");
+ comprintf("\tmov_l_rr(cdata,data);\n");
+ comprintf("\tcmov_l_rr(cdata, zero, NATIVE_CC_NE);\n");
+ comprintf("\tshra_b_rr(cdata,tmpcnt);\n");
+ comprintf("\tmov_b_rr(data,cdata);\n");
+ break;
+ case sz_word:
+ comprintf("\ttest_w_rr(data,data);\n");
+ comprintf("\tcmov_l_rr(zero, minus1, NATIVE_CC_MI);\n");
+ comprintf("\ttest_l_ri(tmpcnt, 0x30);\n");
+ comprintf("\tmov_l_rr(cdata,data);\n");
+ comprintf("\tcmov_l_rr(cdata, zero, NATIVE_CC_NE);\n");
+ comprintf("\tshra_w_rr(cdata,tmpcnt);\n");
+ comprintf("\tmov_w_rr(data,cdata);\n");
+ break;
+ case sz_long:
+ comprintf("\ttest_l_rr(data,data);\n");
+ comprintf("\tcmov_l_rr(zero, minus1, NATIVE_CC_MI);\n");
+ comprintf("\ttest_l_ri(tmpcnt, 0x20);\n");
+ comprintf("\tmov_l_rr(cdata,data);\n");
+ comprintf("\tcmov_l_rr(cdata, zero, NATIVE_CC_NE);\n");
+ comprintf("\tshra_l_rr(cdata,tmpcnt);\n");
+ comprintf("\tmov_l_rr(data,cdata);\n");
+ break;
+ default: assert(0);
+ }
+ /* Result of shift is now in data. */
+ } else {
+ switch (curi->size) {
+ case sz_byte: comprintf("\tshra_b_ri(data,srcreg);\n"); break;
+ case sz_word: comprintf("\tshra_w_ri(data,srcreg);\n"); break;
+ case sz_long: comprintf("\tshra_l_ri(data,srcreg);\n"); break;
+ default: assert(0);
+ }
+ }
/* And create the flags */
- comprintf("\tstart_needflags();\n");
- comprintf("\tif (needed_flags & FLAG_ZNV)\n");
- switch(curi->size) {
- case sz_byte: comprintf("\t test_b_rr(data,data);\n"); break;
- case sz_word: comprintf("\t test_w_rr(data,data);\n"); break;
- case sz_long: comprintf("\t test_l_rr(data,data);\n"); break;
- }
- comprintf("\t bt_l_ri(cdata,0);\n"); /* Set C */
- comprintf("\t live_flags();\n");
- comprintf("\t end_needflags();\n");
- comprintf("\t duplicate_carry();\n");
- comprintf("if (!(needed_flags & FLAG_CZNV)) dont_care_flags();\n");
- genastore ("data", curi->dmode, "dstreg", curi->size, "data");
- }
- else {
- uses_cmov;
- start_brace();
- comprintf("\tint highmask;\n"
- "\tint width;\n"
- "\tint highshift=scratchie++;\n");
- switch(curi->size) {
- case sz_byte: comprintf("\tshra_b_rr(data,cnt);\n"
- "\thighmask=0x38;\n"
- "\twidth=8;\n");
- break;
- case sz_word: comprintf("\tshra_w_rr(data,cnt);\n"
- "\thighmask=0x30;\n"
- "\twidth=16;\n");
- break;
- case sz_long: comprintf("\tshra_l_rr(data,cnt);\n"
- "\thighmask=0x20;\n"
- "\twidth=32;\n");
- break;
- default: assert(0);
- }
- comprintf("test_l_ri(cnt,highmask);\n"
- "mov_l_ri(highshift,0);\n"
- "mov_l_ri(scratchie,width/2);\n"
- "cmov_l_rr(highshift,scratchie,%d);\n",NATIVE_CC_NE);
- /* The x86 masks out bits, so we now make sure that things
- really get shifted as much as planned */
- switch(curi->size) {
- case sz_byte: comprintf("\tshra_b_rr(data,highshift);\n");break;
- case sz_word: comprintf("\tshra_w_rr(data,highshift);\n");break;
- case sz_long: comprintf("\tshra_l_rr(data,highshift);\n");break;
- default: assert(0);
- }
- /* And again */
- switch(curi->size) {
- case sz_byte: comprintf("\tshra_b_rr(data,highshift);\n");break;
- case sz_word: comprintf("\tshra_w_rr(data,highshift);\n");break;
- case sz_long: comprintf("\tshra_l_rr(data,highshift);\n");break;
- default: assert(0);
- }
- genastore ("data", curi->dmode, "dstreg", curi->size, "data");
- }
- }
- else {
- start_brace();
- comprintf("\tint tmp=scratchie++;\n"
- "\tint bp;\n"
- "\tmov_l_rr(tmp,data);\n");
- switch(curi->size) {
- case sz_byte: comprintf("\tshra_b_ri(data,srcreg);\n"
- "\tbp=srcreg-1;\n"); break;
- case sz_word: comprintf("\tshra_w_ri(data,srcreg);\n"
- "\tbp=srcreg-1;\n"); break;
- case sz_long: comprintf("\tshra_l_ri(data,srcreg);\n"
- "\tbp=srcreg-1;\n"); break;
- default: assert(0);
- }
-
- if (!noflags) {
- comprintf("\tstart_needflags();\n");
- comprintf("\tif (needed_flags & FLAG_ZNV)\n");
- switch(curi->size) {
- case sz_byte: comprintf("\t test_b_rr(data,data);\n"); break;
- case sz_word: comprintf("\t test_w_rr(data,data);\n"); break;
- case sz_long: comprintf("\t test_l_rr(data,data);\n"); break;
- }
- comprintf("\t bt_l_ri(tmp,bp);\n"); /* Set C */
- comprintf("\t live_flags();\n");
- comprintf("\t end_needflags();\n");
- comprintf("\t duplicate_carry();\n");
- comprintf("if (!(needed_flags & FLAG_CZNV)) dont_care_flags();\n");
- }
- genastore ("data", curi->dmode, "dstreg", curi->size, "data");
- }
- break;
+ if (!noflags) {
+ comprintf("\tlive_flags();\n");
+ comprintf("\tend_needflags();\n");
+ if (curi->smode != immi)
+ comprintf("\tsetcc_for_cntzero(tmpcnt, data, %d);\n", curi->size == sz_byte ? 1 : curi->size == sz_word ? 2 : 4);
+ else
+ comprintf("\tduplicate_carry();\n");
+ comprintf("if (!(needed_flags & FLAG_CZNV)) dont_care_flags();\n");
+ }
+ genastore("data", curi->dmode, "dstreg", curi->size, "data");
+ break;
- case i_ASL:
+ case i_ASL:
#ifdef DISABLE_I_ASL
- failure;
-#endif
- mayfail;
- if (curi->smode==Dreg) {
- comprintf("if ((uae_u32)srcreg==(uae_u32)dstreg) {\n"
- " FAIL(1);\n"
- " " RETURN "\n"
- "} \n");
- start_brace();
- }
- comprintf("\tdont_care_flags();\n");
- /* Except for the handling of the V flag, this is identical to
- LSL. The handling of V is, uhm, unpleasant, so if it's needed,
- let the normal emulation handle it. Shoulders of giants kinda
- thing ;-) */
- comprintf("if (needed_flags & FLAG_V) {\n"
- " FAIL(1);\n"
- " " RETURN "\n"
- "} \n");
-
- genamode (curi->smode, "srcreg", curi->size, "cnt", 1, 0);
- genamode (curi->dmode, "dstreg", curi->size, "data", 1, 0);
- if (curi->smode!=immi) {
- if (!noflags) {
- uses_cmov;
+ failure;
+#endif
+ mayfail;
+ if (curi->smode == Dreg) {
+ comprintf(
+ " if ((uae_u32)srcreg==(uae_u32)dstreg) {\n"
+ " FAIL(1);\n"
+ " " RETURN "\n"
+ " }\n");
+ start_brace();
+ }
+ comprintf("\tdont_care_flags();\n");
+ /* Except for the handling of the V flag, this is identical to
+ LSL. The handling of V is, uhm, unpleasant, so if it's needed,
+ let the normal emulation handle it. Shoulders of giants kinda
+ thing ;-) */
+ comprintf(
+ " if (needed_flags & FLAG_V) {\n"
+ " FAIL(1);\n"
+ " " RETURN "\n"
+ " }\n");
+
+ genamode(curi->smode, "srcreg", curi->size, "cnt", GENA_GETV_FETCH, GENA_MOVEM_DO_INC);
+ genamode(curi->dmode, "dstreg", curi->size, "data", GENA_GETV_FETCH, GENA_MOVEM_DO_INC);
+
start_brace();
- comprintf("\tint highmask;\n"
- "\tint cdata=scratchie++;\n"
- "\tint tmpcnt=scratchie++;\n");
- comprintf("\tmov_l_rr(tmpcnt,cnt);\n"
- "\tand_l_ri(tmpcnt,63);\n"
- "\tmov_l_ri(cdata,0);\n"
- "\tcmov_l_rr(cdata,data,%d);\n",NATIVE_CC_NE);
- /* cdata is now either data (for shift count!=0) or
- 0 (for shift count==0) */
- switch(curi->size) {
- case sz_byte: comprintf("\tshll_b_rr(data,cnt);\n"
- "\thighmask=0x38;\n");
- break;
- case sz_word: comprintf("\tshll_w_rr(data,cnt);\n"
- "\thighmask=0x30;\n");
- break;
- case sz_long: comprintf("\tshll_l_rr(data,cnt);\n"
- "\thighmask=0x20;\n");
- break;
- default: assert(0);
- }
- comprintf("test_l_ri(cnt,highmask);\n"
- "mov_l_ri(scratchie,0);\n"
- "cmov_l_rr(scratchie,data,%d);\n",NATIVE_CC_EQ);
- switch(curi->size) {
- case sz_byte: comprintf("\tmov_b_rr(data,scratchie);\n");break;
- case sz_word: comprintf("\tmov_w_rr(data,scratchie);\n");break;
- case sz_long: comprintf("\tmov_l_rr(data,scratchie);\n");break;
- default: assert(0);
- }
- /* Result of shift is now in data. Now we need to determine
- the carry by shifting cdata one less */
- comprintf("\tsub_l_ri(tmpcnt,1);\n");
- switch(curi->size) {
- case sz_byte: comprintf("\tshll_b_rr(cdata,tmpcnt);\n");break;
- case sz_word: comprintf("\tshll_w_rr(cdata,tmpcnt);\n");break;
- case sz_long: comprintf("\tshll_l_rr(cdata,tmpcnt);\n");break;
- default: assert(0);
- }
- comprintf("test_l_ri(tmpcnt,highmask);\n"
- "mov_l_ri(scratchie,0);\n"
- "cmov_l_rr(cdata,scratchie,%d);\n",NATIVE_CC_NE);
+ if (!noflags)
+ comprintf("\tstart_needflags();\n");
+ if (curi->smode != immi) {
+ uses_cmov;
+ start_brace();
+ comprintf("\tint cdata = scratchie++;\n");
+ comprintf("\tint tmpcnt=scratchie++;\n");
+ comprintf("\tmov_l_rr(tmpcnt,cnt);\n");
+ comprintf("\tand_l_ri(tmpcnt,63);\n");
+ comprintf("\tmov_l_ri(cdata, 0);\n");
+ switch (curi->size) {
+ case sz_byte:
+ comprintf("\ttest_l_ri(tmpcnt, 0x38);\n");
+ comprintf("\tcmov_l_rr(cdata, data, NATIVE_CC_EQ);\n");
+ comprintf("\tshll_b_rr(cdata,tmpcnt);\n");
+ comprintf("\tmov_b_rr(data, cdata);\n");
+ break;
+ case sz_word:
+ comprintf("\ttest_l_ri(tmpcnt, 0x30);\n");
+ comprintf("\tcmov_l_rr(cdata, data, NATIVE_CC_EQ);\n");
+ comprintf("\tshll_w_rr(cdata,tmpcnt);\n");
+ comprintf("\tmov_w_rr(data, cdata);\n");
+ break;
+ case sz_long:
+ comprintf("\ttest_l_ri(tmpcnt, 0x20);\n");
+ comprintf("\tcmov_l_rr(cdata, data, NATIVE_CC_EQ);\n");
+ comprintf("\tshll_l_rr(cdata,tmpcnt);\n");
+ comprintf("\tmov_l_rr(data, cdata);\n");
+ break;
+ default: assert(0);
+ }
+ /* Result of shift is now in data. */
+ } else {
+ switch (curi->size) {
+ case sz_byte: comprintf("\tshll_b_ri(data,srcreg);\n"); break;
+ case sz_word: comprintf("\tshll_w_ri(data,srcreg);\n"); break;
+ case sz_long: comprintf("\tshll_l_ri(data,srcreg);\n"); break;
+ default: assert(0);
+ }
+ }
/* And create the flags */
- comprintf("\tstart_needflags();\n");
-
- comprintf("\tif (needed_flags & FLAG_ZNV)\n");
- switch(curi->size) {
- case sz_byte: comprintf("\t test_b_rr(data,data);\n");
- comprintf("\t bt_l_ri(cdata,7);\n"); break;
- case sz_word: comprintf("\t test_w_rr(data,data);\n");
- comprintf("\t bt_l_ri(cdata,15);\n"); break;
- case sz_long: comprintf("\t test_l_rr(data,data);\n");
- comprintf("\t bt_l_ri(cdata,31);\n"); break;
- }
- comprintf("\t live_flags();\n");
- comprintf("\t end_needflags();\n");
- comprintf("\t duplicate_carry();\n");
- comprintf("if (!(needed_flags & FLAG_CZNV)) dont_care_flags();\n");
- genastore ("data", curi->dmode, "dstreg", curi->size, "data");
- }
- else {
- uses_cmov;
- start_brace();
- comprintf("\tint highmask;\n");
- switch(curi->size) {
- case sz_byte: comprintf("\tshll_b_rr(data,cnt);\n"
- "\thighmask=0x38;\n");
- break;
- case sz_word: comprintf("\tshll_w_rr(data,cnt);\n"
- "\thighmask=0x30;\n");
- break;
- case sz_long: comprintf("\tshll_l_rr(data,cnt);\n"
- "\thighmask=0x20;\n");
- break;
- default: assert(0);
- }
- comprintf("test_l_ri(cnt,highmask);\n"
- "mov_l_ri(scratchie,0);\n"
- "cmov_l_rr(scratchie,data,%d);\n",NATIVE_CC_EQ);
- switch(curi->size) {
- case sz_byte: comprintf("\tmov_b_rr(data,scratchie);\n");break;
- case sz_word: comprintf("\tmov_w_rr(data,scratchie);\n");break;
- case sz_long: comprintf("\tmov_l_rr(data,scratchie);\n");break;
- default: assert(0);
- }
- genastore ("data", curi->dmode, "dstreg", curi->size, "data");
- }
- }
- else {
- start_brace();
- comprintf("\tint tmp=scratchie++;\n"
- "\tint bp;\n"
- "\tmov_l_rr(tmp,data);\n");
- switch(curi->size) {
- case sz_byte: comprintf("\tshll_b_ri(data,srcreg);\n"
- "\tbp=8-srcreg;\n"); break;
- case sz_word: comprintf("\tshll_w_ri(data,srcreg);\n"
- "\tbp=16-srcreg;\n"); break;
- case sz_long: comprintf("\tshll_l_ri(data,srcreg);\n"
- "\tbp=32-srcreg;\n"); break;
- default: assert(0);
- }
-
- if (!noflags) {
- comprintf("\tstart_needflags();\n");
- comprintf("\tif (needed_flags & FLAG_ZNV)\n");
- switch(curi->size) {
- case sz_byte: comprintf("\t test_b_rr(data,data);\n"); break;
- case sz_word: comprintf("\t test_w_rr(data,data);\n"); break;
- case sz_long: comprintf("\t test_l_rr(data,data);\n"); break;
- }
- comprintf("\t bt_l_ri(tmp,bp);\n"); /* Set C */
- comprintf("\t live_flags();\n");
- comprintf("\t end_needflags();\n");
- comprintf("\t duplicate_carry();\n");
- comprintf("if (!(needed_flags & FLAG_CZNV)) dont_care_flags();\n");
- }
- genastore ("data", curi->dmode, "dstreg", curi->size, "data");
- }
- break;
+ if (!noflags) {
+ comprintf("\tlive_flags();\n");
+ comprintf("\tend_needflags();\n");
+ if (curi->smode != immi)
+ comprintf("\tsetcc_for_cntzero(tmpcnt, data, %d);\n", curi->size == sz_byte ? 1 : curi->size == sz_word ? 2 : 4);
+ else
+ comprintf("\tduplicate_carry();\n");
+ comprintf("if (!(needed_flags & FLAG_CZNV)) dont_care_flags();\n");
+ }
+ genastore("data", curi->dmode, "dstreg", curi->size, "data");
+ break;
- case i_LSR:
+ case i_LSR:
#ifdef DISABLE_I_LSR
- failure;
-#endif
- mayfail;
- if (curi->smode==Dreg) {
- comprintf("if ((uae_u32)srcreg==(uae_u32)dstreg) {\n"
- " FAIL(1);\n"
- " " RETURN "\n"
- "} \n");
- start_brace();
- }
- comprintf("\tdont_care_flags();\n");
+ failure;
+#endif
+ mayfail;
+ if (curi->smode == Dreg) {
+ comprintf(
+ " if ((uae_u32)srcreg==(uae_u32)dstreg) {\n"
+ " FAIL(1);\n"
+ " " RETURN "\n"
+ " }\n");
+ start_brace();
+ }
+ comprintf("\tdont_care_flags();\n");
+
+ genamode(curi->smode, "srcreg", curi->size, "cnt", GENA_GETV_FETCH, GENA_MOVEM_DO_INC);
+ genamode(curi->dmode, "dstreg", curi->size, "data", GENA_GETV_FETCH, GENA_MOVEM_DO_INC);
- genamode (curi->smode, "srcreg", curi->size, "cnt", 1, 0);
- genamode (curi->dmode, "dstreg", curi->size, "data", 1, 0);
- if (curi->smode!=immi) {
- if (!noflags) {
- uses_cmov;
start_brace();
- comprintf("\tint highmask;\n"
- "\tint cdata=scratchie++;\n"
- "\tint tmpcnt=scratchie++;\n");
- comprintf("\tmov_l_rr(tmpcnt,cnt);\n"
- "\tand_l_ri(tmpcnt,63);\n"
- "\tmov_l_ri(cdata,0);\n"
- "\tcmov_l_rr(cdata,data,%d);\n",NATIVE_CC_NE);
- /* cdata is now either data (for shift count!=0) or
- 0 (for shift count==0) */
- switch(curi->size) {
- case sz_byte: comprintf("\tshrl_b_rr(data,cnt);\n"
- "\thighmask=0x38;\n");
- break;
- case sz_word: comprintf("\tshrl_w_rr(data,cnt);\n"
- "\thighmask=0x30;\n");
- break;
- case sz_long: comprintf("\tshrl_l_rr(data,cnt);\n"
- "\thighmask=0x20;\n");
- break;
- default: assert(0);
- }
- comprintf("test_l_ri(cnt,highmask);\n"
- "mov_l_ri(scratchie,0);\n"
- "cmov_l_rr(scratchie,data,%d);\n",NATIVE_CC_EQ);
- switch(curi->size) {
- case sz_byte: comprintf("\tmov_b_rr(data,scratchie);\n");break;
- case sz_word: comprintf("\tmov_w_rr(data,scratchie);\n");break;
- case sz_long: comprintf("\tmov_l_rr(data,scratchie);\n");break;
- default: assert(0);
- }
- /* Result of shift is now in data. Now we need to determine
- the carry by shifting cdata one less */
- comprintf("\tsub_l_ri(tmpcnt,1);\n");
- switch(curi->size) {
- case sz_byte: comprintf("\tshrl_b_rr(cdata,tmpcnt);\n");break;
- case sz_word: comprintf("\tshrl_w_rr(cdata,tmpcnt);\n");break;
- case sz_long: comprintf("\tshrl_l_rr(cdata,tmpcnt);\n");break;
- default: assert(0);
- }
- comprintf("test_l_ri(tmpcnt,highmask);\n"
- "mov_l_ri(scratchie,0);\n"
- "cmov_l_rr(cdata,scratchie,%d);\n",NATIVE_CC_NE);
+ if (!noflags)
+ comprintf("\tstart_needflags();\n");
+ if (curi->smode != immi) {
+ uses_cmov;
+ start_brace();
+ comprintf("\tint cdata = scratchie++;\n");
+ comprintf("\tint tmpcnt=scratchie++;\n");
+ comprintf("\tmov_l_rr(tmpcnt,cnt);\n");
+ comprintf("\tand_l_ri(tmpcnt,63);\n");
+ comprintf("\tmov_l_ri(cdata, 0);\n");
+ switch (curi->size) {
+ case sz_byte:
+ comprintf("\ttest_l_ri(tmpcnt, 0x38);\n");
+ comprintf("\tcmov_l_rr(cdata, data, NATIVE_CC_EQ);\n");
+ comprintf("\tshrl_b_rr(cdata,tmpcnt);\n");
+ comprintf("\tmov_b_rr(data, cdata);\n");
+ break;
+ case sz_word:
+ comprintf("\ttest_l_ri(tmpcnt, 0x30);\n");
+ comprintf("\tcmov_l_rr(cdata, data, NATIVE_CC_EQ);\n");
+ comprintf("\tshrl_w_rr(cdata,tmpcnt);\n");
+ comprintf("\tmov_w_rr(data, cdata);\n");
+ break;
+ case sz_long:
+ comprintf("\ttest_l_ri(tmpcnt, 0x20);\n");
+ comprintf("\tcmov_l_rr(cdata, data, NATIVE_CC_EQ);\n");
+ comprintf("\tshrl_l_rr(cdata, tmpcnt);\n");
+ comprintf("\tmov_l_rr(data, cdata);\n");
+ break;
+ default: assert(0);
+ }
+ /* Result of shift is now in data. */
+ } else {
+ switch (curi->size) {
+ case sz_byte: comprintf("\tshrl_b_ri(data,srcreg);\n"); break;
+ case sz_word: comprintf("\tshrl_w_ri(data,srcreg);\n"); break;
+ case sz_long: comprintf("\tshrl_l_ri(data,srcreg);\n"); break;
+ default: assert(0);
+ }
+ }
/* And create the flags */
- comprintf("\tstart_needflags();\n");
- comprintf("\tif (needed_flags & FLAG_ZNV)\n");
- switch(curi->size) {
- case sz_byte: comprintf("\t test_b_rr(data,data);\n"); break;
- case sz_word: comprintf("\t test_w_rr(data,data);\n"); break;
- case sz_long: comprintf("\t test_l_rr(data,data);\n"); break;
- }
- comprintf("\t bt_l_ri(cdata,0);\n"); /* Set C */
- comprintf("\t live_flags();\n");
- comprintf("\t end_needflags();\n");
- comprintf("\t duplicate_carry();\n");
- comprintf("if (!(needed_flags & FLAG_CZNV)) dont_care_flags();\n");
- genastore ("data", curi->dmode, "dstreg", curi->size, "data");
- }
- else {
- uses_cmov;
- start_brace();
- comprintf("\tint highmask;\n");
- switch(curi->size) {
- case sz_byte: comprintf("\tshrl_b_rr(data,cnt);\n"
- "\thighmask=0x38;\n");
- break;
- case sz_word: comprintf("\tshrl_w_rr(data,cnt);\n"
- "\thighmask=0x30;\n");
- break;
- case sz_long: comprintf("\tshrl_l_rr(data,cnt);\n"
- "\thighmask=0x20;\n");
- break;
- default: assert(0);
- }
- comprintf("test_l_ri(cnt,highmask);\n"
- "mov_l_ri(scratchie,0);\n"
- "cmov_l_rr(scratchie,data,%d);\n",NATIVE_CC_EQ);
- switch(curi->size) {
- case sz_byte: comprintf("\tmov_b_rr(data,scratchie);\n");break;
- case sz_word: comprintf("\tmov_w_rr(data,scratchie);\n");break;
- case sz_long: comprintf("\tmov_l_rr(data,scratchie);\n");break;
- default: assert(0);
- }
- genastore ("data", curi->dmode, "dstreg", curi->size, "data");
- }
- }
- else {
- start_brace();
- comprintf("\tint tmp=scratchie++;\n"
- "\tint bp;\n"
- "\tmov_l_rr(tmp,data);\n");
- switch(curi->size) {
- case sz_byte: comprintf("\tshrl_b_ri(data,srcreg);\n"
- "\tbp=srcreg-1;\n"); break;
- case sz_word: comprintf("\tshrl_w_ri(data,srcreg);\n"
- "\tbp=srcreg-1;\n"); break;
- case sz_long: comprintf("\tshrl_l_ri(data,srcreg);\n"
- "\tbp=srcreg-1;\n"); break;
- default: assert(0);
- }
-
- if (!noflags) {
- comprintf("\tstart_needflags();\n");
- comprintf("\tif (needed_flags & FLAG_ZNV)\n");
- switch(curi->size) {
- case sz_byte: comprintf("\t test_b_rr(data,data);\n"); break;
- case sz_word: comprintf("\t test_w_rr(data,data);\n"); break;
- case sz_long: comprintf("\t test_l_rr(data,data);\n"); break;
- }
- comprintf("\t bt_l_ri(tmp,bp);\n"); /* Set C */
- comprintf("\t live_flags();\n");
- comprintf("\t end_needflags();\n");
- comprintf("\t duplicate_carry();\n");
- comprintf("if (!(needed_flags & FLAG_CZNV)) dont_care_flags();\n");
- }
- genastore ("data", curi->dmode, "dstreg", curi->size, "data");
- }
- break;
+ if (!noflags) {
+ comprintf("\tlive_flags();\n");
+ comprintf("\tend_needflags();\n");
+ if (curi->smode != immi)
+ comprintf("\tsetcc_for_cntzero(tmpcnt, data, %d);\n", curi->size == sz_byte ? 1 : curi->size == sz_word ? 2 : 4);
+ else
+ comprintf("\tduplicate_carry();\n");
+ comprintf("if (!(needed_flags & FLAG_CZNV)) dont_care_flags();\n");
+ }
+ genastore("data", curi->dmode, "dstreg", curi->size, "data");
+ break;
- case i_LSL:
+ case i_LSL:
#ifdef DISABLE_I_LSL
- failure;
-#endif
- mayfail;
- if (curi->smode==Dreg) {
- comprintf("if ((uae_u32)srcreg==(uae_u32)dstreg) {\n"
- " FAIL(1);\n"
- " " RETURN "\n"
- "} \n");
- start_brace();
- }
- comprintf("\tdont_care_flags();\n");
+ failure;
+#endif
+ mayfail;
+ if (curi->smode == Dreg) {
+ comprintf(
+ " if ((uae_u32)srcreg==(uae_u32)dstreg) {\n"
+ " FAIL(1);\n"
+ " " RETURN "\n"
+ " }\n");
+ start_brace();
+ }
+ comprintf("\tdont_care_flags();\n");
+
+ genamode(curi->smode, "srcreg", curi->size, "cnt", GENA_GETV_FETCH, GENA_MOVEM_DO_INC);
+ genamode(curi->dmode, "dstreg", curi->size, "data", GENA_GETV_FETCH, GENA_MOVEM_DO_INC);
- genamode (curi->smode, "srcreg", curi->size, "cnt", 1, 0);
- genamode (curi->dmode, "dstreg", curi->size, "data", 1, 0);
- if (curi->smode!=immi) {
- if (!noflags) {
- uses_cmov;
start_brace();
- comprintf("\tint highmask;\n"
- "\tint cdata=scratchie++;\n"
- "\tint tmpcnt=scratchie++;\n");
- comprintf("\tmov_l_rr(tmpcnt,cnt);\n"
- "\tand_l_ri(tmpcnt,63);\n"
- "\tmov_l_ri(cdata,0);\n"
- "\tcmov_l_rr(cdata,data,%d);\n",NATIVE_CC_NE);
- /* cdata is now either data (for shift count!=0) or
- 0 (for shift count==0) */
- switch(curi->size) {
- case sz_byte: comprintf("\tshll_b_rr(data,cnt);\n"
- "\thighmask=0x38;\n");
- break;
- case sz_word: comprintf("\tshll_w_rr(data,cnt);\n"
- "\thighmask=0x30;\n");
- break;
- case sz_long: comprintf("\tshll_l_rr(data,cnt);\n"
- "\thighmask=0x20;\n");
- break;
- default: assert(0);
- }
- comprintf("test_l_ri(cnt,highmask);\n"
- "mov_l_ri(scratchie,0);\n"
- "cmov_l_rr(scratchie,data,%d);\n",NATIVE_CC_EQ);
- switch(curi->size) {
- case sz_byte: comprintf("\tmov_b_rr(data,scratchie);\n");break;
- case sz_word: comprintf("\tmov_w_rr(data,scratchie);\n");break;
- case sz_long: comprintf("\tmov_l_rr(data,scratchie);\n");break;
- default: assert(0);
- }
- /* Result of shift is now in data. Now we need to determine
- the carry by shifting cdata one less */
- comprintf("\tsub_l_ri(tmpcnt,1);\n");
- switch(curi->size) {
- case sz_byte: comprintf("\tshll_b_rr(cdata,tmpcnt);\n");break;
- case sz_word: comprintf("\tshll_w_rr(cdata,tmpcnt);\n");break;
- case sz_long: comprintf("\tshll_l_rr(cdata,tmpcnt);\n");break;
- default: assert(0);
- }
- comprintf("test_l_ri(tmpcnt,highmask);\n"
- "mov_l_ri(scratchie,0);\n"
- "cmov_l_rr(cdata,scratchie,%d);\n",NATIVE_CC_NE);
+ if (!noflags)
+ comprintf("\tstart_needflags();\n");
+ if (curi->smode != immi) {
+ uses_cmov;
+ start_brace();
+ comprintf("\tint cdata = scratchie++;\n");
+ comprintf("\tint tmpcnt = scratchie++;\n");
+ comprintf("\tmov_l_rr(tmpcnt,cnt);\n");
+ comprintf("\tand_l_ri(tmpcnt,63);\n");
+ comprintf("\tmov_l_ri(cdata, 0);\n");
+ switch (curi->size) {
+ case sz_byte:
+ comprintf("\ttest_l_ri(tmpcnt, 0x38);\n");
+ comprintf("\tcmov_l_rr(cdata, data, NATIVE_CC_EQ);\n");
+ comprintf("\tshll_b_rr(cdata,tmpcnt);\n");
+ comprintf("\tmov_b_rr(data, cdata);\n");
+ break;
+ case sz_word:
+ comprintf("\ttest_l_ri(tmpcnt, 0x30);\n");
+ comprintf("\tcmov_l_rr(cdata, data, NATIVE_CC_EQ);\n");
+ comprintf("\tshll_w_rr(cdata,tmpcnt);\n");
+ comprintf("\tmov_w_rr(data, cdata);\n");
+ break;
+ case sz_long:
+ comprintf("\ttest_l_ri(tmpcnt, 0x20);\n");
+ comprintf("\tcmov_l_rr(cdata, data, NATIVE_CC_EQ);\n");
+ comprintf("\tshll_l_rr(cdata,tmpcnt);\n");
+ comprintf("\tmov_l_rr(data, cdata);\n");
+ break;
+ default: assert(0);
+ }
+ /* Result of shift is now in data. */
+ } else {
+ switch (curi->size) {
+ case sz_byte: comprintf("\tshll_b_ri(data,srcreg);\n"); break;
+ case sz_word: comprintf("\tshll_w_ri(data,srcreg);\n"); break;
+ case sz_long: comprintf("\tshll_l_ri(data,srcreg);\n"); break;
+ default: assert(0);
+ }
+ }
/* And create the flags */
- comprintf("\tstart_needflags();\n");
- comprintf("\tif (needed_flags & FLAG_ZNV)\n");
- switch(curi->size) {
- case sz_byte: comprintf("\t test_b_rr(data,data);\n");
- comprintf("\t bt_l_ri(cdata,7);\n"); break;
- case sz_word: comprintf("\t test_w_rr(data,data);\n");
- comprintf("\t bt_l_ri(cdata,15);\n"); break;
- case sz_long: comprintf("\t test_l_rr(data,data);\n");
- comprintf("\t bt_l_ri(cdata,31);\n"); break;
- }
- comprintf("\t live_flags();\n");
- comprintf("\t end_needflags();\n");
- comprintf("\t duplicate_carry();\n");
- comprintf("if (!(needed_flags & FLAG_CZNV)) dont_care_flags();\n");
- genastore ("data", curi->dmode, "dstreg", curi->size, "data");
- }
- else {
- uses_cmov;
- start_brace();
- comprintf("\tint highmask;\n");
- switch(curi->size) {
- case sz_byte: comprintf("\tshll_b_rr(data,cnt);\n"
- "\thighmask=0x38;\n");
- break;
- case sz_word: comprintf("\tshll_w_rr(data,cnt);\n"
- "\thighmask=0x30;\n");
- break;
- case sz_long: comprintf("\tshll_l_rr(data,cnt);\n"
- "\thighmask=0x20;\n");
- break;
- default: assert(0);
- }
- comprintf("test_l_ri(cnt,highmask);\n"
- "mov_l_ri(scratchie,0);\n"
- "cmov_l_rr(scratchie,data,%d);\n",NATIVE_CC_EQ);
- switch(curi->size) {
- case sz_byte: comprintf("\tmov_b_rr(data,scratchie);\n");break;
- case sz_word: comprintf("\tmov_w_rr(data,scratchie);\n");break;
- case sz_long: comprintf("\tmov_l_rr(data,scratchie);\n");break;
- default: assert(0);
- }
- genastore ("data", curi->dmode, "dstreg", curi->size, "data");
- }
- }
- else {
- start_brace();
- comprintf("\tint tmp=scratchie++;\n"
- "\tint bp;\n"
- "\tmov_l_rr(tmp,data);\n");
- switch(curi->size) {
- case sz_byte: comprintf("\tshll_b_ri(data,srcreg);\n"
- "\tbp=8-srcreg;\n"); break;
- case sz_word: comprintf("\tshll_w_ri(data,srcreg);\n"
- "\tbp=16-srcreg;\n"); break;
- case sz_long: comprintf("\tshll_l_ri(data,srcreg);\n"
- "\tbp=32-srcreg;\n"); break;
- default: assert(0);
- }
-
- if (!noflags) {
- comprintf("\tstart_needflags();\n");
- comprintf("\tif (needed_flags & FLAG_ZNV)\n");
- switch(curi->size) {
- case sz_byte: comprintf("\t test_b_rr(data,data);\n"); break;
- case sz_word: comprintf("\t test_w_rr(data,data);\n"); break;
- case sz_long: comprintf("\t test_l_rr(data,data);\n"); break;
- }
- comprintf("\t bt_l_ri(tmp,bp);\n"); /* Set C */
- comprintf("\t live_flags();\n");
- comprintf("\t end_needflags();\n");
- comprintf("\t duplicate_carry();\n");
- comprintf("if (!(needed_flags & FLAG_CZNV)) dont_care_flags();\n");
- }
- genastore ("data", curi->dmode, "dstreg", curi->size, "data");
- }
- break;
+ if (!noflags) {
+ comprintf("\tlive_flags();\n");
+ comprintf("\tend_needflags();\n");
+ if (curi->smode != immi)
+ comprintf("\tsetcc_for_cntzero(tmpcnt, data, %d);\n", curi->size == sz_byte ? 1 : curi->size == sz_word ? 2 : 4);
+ else
+ comprintf("\tduplicate_carry();\n");
+ comprintf("if (!(needed_flags & FLAG_CZNV)) dont_care_flags();\n");
+ }
+ genastore("data", curi->dmode, "dstreg", curi->size, "data");
+ break;
- case i_ROL:
+ case i_ROL:
#ifdef DISABLE_I_ROL
- failure;
-#endif
- mayfail;
- if (curi->smode==Dreg) {
- comprintf("if ((uae_u32)srcreg==(uae_u32)dstreg) {\n"
- " FAIL(1);\n"
- " " RETURN "\n"
- "} \n");
- start_brace();
- }
- comprintf("\tdont_care_flags();\n");
- genamode (curi->smode, "srcreg", curi->size, "cnt", 1, 0);
- genamode (curi->dmode, "dstreg", curi->size, "data", 1, 0);
- start_brace ();
-
- switch(curi->size) {
- case sz_long: comprintf("\t rol_l_rr(data,cnt);\n"); break;
- case sz_word: comprintf("\t rol_w_rr(data,cnt);\n"); break;
- case sz_byte: comprintf("\t rol_b_rr(data,cnt);\n"); break;
- }
+ failure;
+#endif
+ mayfail;
+ if (curi->smode == Dreg) {
+ comprintf(
+ " if ((uae_u32)srcreg==(uae_u32)dstreg) {\n"
+ " FAIL(1);\n"
+ " " RETURN "\n"
+ " }\n");
+ start_brace();
+ }
+ comprintf("\tdont_care_flags();\n");
+ genamode(curi->smode, "srcreg", curi->size, "cnt", GENA_GETV_FETCH, GENA_MOVEM_DO_INC);
+ genamode(curi->dmode, "dstreg", curi->size, "data", GENA_GETV_FETCH, GENA_MOVEM_DO_INC);
+ start_brace();
- if (!noflags) {
- comprintf("\tstart_needflags();\n");
- comprintf("\tif (needed_flags & FLAG_ZNV)\n");
- switch(curi->size) {
- case sz_byte: comprintf("\t test_b_rr(data,data);\n"); break;
- case sz_word: comprintf("\t test_w_rr(data,data);\n"); break;
- case sz_long: comprintf("\t test_l_rr(data,data);\n"); break;
- }
- comprintf("\t bt_l_ri(data,0x00);\n"); /* Set C */
- comprintf("\t live_flags();\n");
- comprintf("\t end_needflags();\n");
- }
- genastore ("data", curi->dmode, "dstreg", curi->size, "data");
- break;
+ switch (curi->size) {
+ case sz_long: comprintf("\trol_l_rr(data,cnt);\n"); break;
+ case sz_word: comprintf("\trol_w_rr(data,cnt);\n"); break;
+ case sz_byte: comprintf("\trol_b_rr(data,cnt);\n"); break;
+ }
+
+ if (!noflags) {
+ comprintf("\tstart_needflags();\n");
+ /*
+ * x86 ROL instruction does not set ZF/SF, so we need extra checks here
+ */
+ comprintf("\tif (needed_flags & FLAG_ZNV)\n");
+ switch (curi->size) {
+ case sz_byte: comprintf("\t test_b_rr(data,data);\n"); break;
+ case sz_word: comprintf("\t test_w_rr(data,data);\n"); break;
+ case sz_long: comprintf("\t test_l_rr(data,data);\n"); break;
+ }
+ comprintf("\tbt_l_ri(data,0x00);\n"); /* Set C */
+ comprintf("\tlive_flags();\n");
+ comprintf("\tend_needflags();\n");
+ }
+ genastore("data", curi->dmode, "dstreg", curi->size, "data");
+ break;
- case i_ROR:
+ case i_ROR:
#ifdef DISABLE_I_ROR
- failure;
-#endif
- mayfail;
- if (curi->smode==Dreg) {
- comprintf("if ((uae_u32)srcreg==(uae_u32)dstreg) {\n"
- " FAIL(1);\n"
- " " RETURN "\n"
- "} \n");
- start_brace();
- }
- comprintf("\tdont_care_flags();\n");
- genamode (curi->smode, "srcreg", curi->size, "cnt", 1, 0);
- genamode (curi->dmode, "dstreg", curi->size, "data", 1, 0);
- start_brace ();
-
- switch(curi->size) {
- case sz_long: comprintf("\t ror_l_rr(data,cnt);\n"); break;
- case sz_word: comprintf("\t ror_w_rr(data,cnt);\n"); break;
- case sz_byte: comprintf("\t ror_b_rr(data,cnt);\n"); break;
- }
+ failure;
+#endif
+ mayfail;
+ if (curi->smode == Dreg) {
+ comprintf(
+ " if ((uae_u32)srcreg==(uae_u32)dstreg) {\n"
+ " FAIL(1);\n"
+ " " RETURN "\n"
+ " }\n");
+ start_brace();
+ }
+ comprintf("\tdont_care_flags();\n");
+ genamode(curi->smode, "srcreg", curi->size, "cnt", GENA_GETV_FETCH, GENA_MOVEM_DO_INC);
+ genamode(curi->dmode, "dstreg", curi->size, "data", GENA_GETV_FETCH, GENA_MOVEM_DO_INC);
+ start_brace();
- if (!noflags) {
- comprintf("\tstart_needflags();\n");
- comprintf("\tif (needed_flags & FLAG_ZNV)\n");
- switch(curi->size) {
- case sz_byte: comprintf("\t test_b_rr(data,data);\n"); break;
- case sz_word: comprintf("\t test_w_rr(data,data);\n"); break;
- case sz_long: comprintf("\t test_l_rr(data,data);\n"); break;
- }
- switch(curi->size) {
- case sz_byte: comprintf("\t bt_l_ri(data,0x07);\n"); break;
- case sz_word: comprintf("\t bt_l_ri(data,0x0f);\n"); break;
- case sz_long: comprintf("\t bt_l_ri(data,0x1f);\n"); break;
- }
- comprintf("\t live_flags();\n");
- comprintf("\t end_needflags();\n");
- }
- genastore ("data", curi->dmode, "dstreg", curi->size, "data");
- break;
+ switch (curi->size) {
+ case sz_long: comprintf("\tror_l_rr(data,cnt);\n"); break;
+ case sz_word: comprintf("\tror_w_rr(data,cnt);\n"); break;
+ case sz_byte: comprintf("\tror_b_rr(data,cnt);\n"); break;
+ }
- case i_ROXL:
- failure;
- break;
+ if (!noflags) {
+ comprintf("\tstart_needflags();\n");
+ /*
+ * x86 ROR instruction does not set ZF/SF, so we need extra checks here
+ */
+ comprintf("\tif (needed_flags & FLAG_ZNV)\n");
+ switch (curi->size) {
+ case sz_byte: comprintf("\t test_b_rr(data,data);\n"); break;
+ case sz_word: comprintf("\t test_w_rr(data,data);\n"); break;
+ case sz_long: comprintf("\t test_l_rr(data,data);\n"); break;
+ }
+ switch (curi->size) {
+ case sz_byte: comprintf("\tbt_l_ri(data,0x07);\n"); break;
+ case sz_word: comprintf("\tbt_l_ri(data,0x0f);\n"); break;
+ case sz_long: comprintf("\tbt_l_ri(data,0x1f);\n"); break;
+ }
+ comprintf("\tlive_flags();\n");
+ comprintf("\tend_needflags();\n");
+ }
+ genastore("data", curi->dmode, "dstreg", curi->size, "data");
+ break;
- case i_ROXR:
- failure;
- break;
+ case i_ROXL:
+ failure;
+ break;
- case i_ASRW:
- failure;
- break;
+ case i_ROXR:
+ failure;
+ break;
- case i_ASLW:
- failure;
- break;
+ case i_ASRW:
+ failure;
+ break;
- case i_LSRW:
- failure;
- break;
+ case i_ASLW:
+ failure;
+ break;
- case i_LSLW:
- failure;
- break;
+ case i_LSRW:
+ failure;
+ break;
- case i_ROLW:
- failure;
- break;
+ case i_LSLW:
+ failure;
+ break;
- case i_RORW:
- failure;
- break;
+ case i_ROLW:
+ failure;
+ break;
- case i_ROXLW:
- failure;
- break;
+ case i_RORW:
+ failure;
+ break;
- case i_ROXRW:
- failure;
- break;
+ case i_ROXLW:
+ failure;
+ break;
- case i_MOVEC2:
- isjump;
- failure;
- break;
+ case i_ROXRW:
+ failure;
+ break;
- case i_MOVE2C:
- isjump;
- failure;
- break;
+ case i_MOVEC2:
+ isjump;
+ failure;
+ break;
- case i_CAS:
- failure;
- break;
+ case i_MOVE2C:
+ isjump;
+ failure;
+ break;
- case i_CAS2:
- failure;
- break;
+ case i_CAS:
+ failure;
+ break;
- case i_MOVES: /* ignore DFC and SFC because we have no MMU */
- isjump;
- failure;
- break;
+ case i_CAS2:
+ failure;
+ break;
- case i_BKPT: /* only needed for hardware emulators */
- isjump;
- failure;
- break;
+ case i_MOVES: /* ignore DFC and SFC because we have no MMU */
+ isjump;
+ failure;
+ break;
- case i_CALLM: /* not present in 68030 */
- isjump;
- failure;
- break;
+ case i_BKPT: /* only needed for hardware emulators */
+ isjump;
+ failure;
+ break;
- case i_RTM: /* not present in 68030 */
- isjump;
- failure;
- break;
+ case i_CALLM: /* not present in 68030 */
+ isjump;
+ failure;
+ break;
- case i_TRAPcc:
- isjump;
- failure;
- break;
+ case i_RTM: /* not present in 68030 */
+ isjump;
+ failure;
+ break;
- case i_DIVL:
- isjump;
- failure;
- break;
+ case i_TRAPcc:
+ isjump;
+ failure;
+ break;
- case i_MULL:
+ case i_DIVL:
+ isjump;
+ failure;
+ break;
+
+ case i_MULL:
#ifdef DISABLE_I_MULL
- failure;
+ failure;
#endif
- if (!noflags) {
- failure;
- break;
- }
- comprintf("\tuae_u16 extra=%s;\n",gen_nextiword());
- comprintf("\tint r2=(extra>>12)&7;\n"
- "\tint tmp=scratchie++;\n");
-
- genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0);
- /* The two operands are in dst and r2 */
- comprintf("\tif (extra&0x0400) {\n" /* Need full 64 bit result */
- "\tint r3=(extra&7);\n"
- "\tmov_l_rr(r3,dst);\n"); /* operands now in r3 and r2 */
- comprintf("\tif (extra&0x0800) { \n" /* signed */
- "\t\timul_64_32(r2,r3);\n"
- "\t} else { \n"
- "\t\tmul_64_32(r2,r3);\n"
- "\t} \n");
- /* The result is in r2/tmp, with r2 holding the lower 32 bits */
- comprintf("\t} else {\n"); /* Only want 32 bit result */
- /* operands in dst and r2, result foes into r2 */
- /* shouldn't matter whether it's signed or unsigned?!? */
- comprintf("\timul_32_32(r2,dst);\n"
- "\t}\n");
- break;
+ if (!noflags) {
+ failure;
+ break;
+ }
+ comprintf("\tuae_u16 extra=%s;\n", gen_nextiword());
+ comprintf("\tint r2=(extra>>12)&7;\n"
+ "\tint tmp=scratchie++;\n");
+
+ genamode(curi->dmode, "dstreg", curi->size, "dst", GENA_GETV_FETCH, GENA_MOVEM_DO_INC);
+ /* The two operands are in dst and r2 */
+ comprintf("\tif (extra&0x0400) {\n" /* Need full 64 bit result */
+ "\tint r3=(extra&7);\n"
+ "\tmov_l_rr(r3,dst);\n"); /* operands now in r3 and r2 */
+ comprintf("\tif (extra&0x0800) { \n" /* signed */
+ "\t\timul_64_32(r2,r3);\n"
+ "\t} else { \n"
+ "\t\tmul_64_32(r2,r3);\n"
+ "\t} \n");
+ /* The result is in r2/tmp, with r2 holding the lower 32 bits */
+ comprintf("\t} else {\n"); /* Only want 32 bit result */
+ /* operands in dst and r2, result foes into r2 */
+ /* shouldn't matter whether it's signed or unsigned?!? */
+ comprintf("\timul_32_32(r2,dst);\n"
+ "\t}\n");
+ break;
- case i_BFTST:
- case i_BFEXTU:
- case i_BFCHG:
- case i_BFEXTS:
- case i_BFCLR:
- case i_BFFFO:
- case i_BFSET:
- case i_BFINS:
- failure;
- break;
+ case i_BFTST:
+ case i_BFEXTU:
+ case i_BFCHG:
+ case i_BFEXTS:
+ case i_BFCLR:
+ case i_BFFFO:
+ case i_BFSET:
+ case i_BFINS:
+ failure;
+ break;
- case i_PACK:
- failure;
- break;
+ case i_PACK:
+ failure;
+ break;
- case i_UNPK:
- failure;
- break;
+ case i_UNPK:
+ failure;
+ break;
- case i_TAS:
- failure;
- break;
+ case i_TAS:
+ failure;
+ break;
- case i_FPP:
+ case i_FPP:
#ifdef DISABLE_I_FPP
- failure;
-#endif
- uses_fpu;
- mayfail;
- comprintf("#ifdef USE_JIT_FPU\n");
- comprintf("\tuae_u16 extra=%s;\n",gen_nextiword());
- swap_opcode();
- comprintf("\tcomp_fpp_opp(opcode,extra);\n");
- comprintf("#else\n");
- comprintf("\tfailure = 1;\n");
- comprintf("#endif\n");
- break;
+ failure;
+#endif
+ uses_fpu;
+ mayfail;
+ comprintf("#ifdef USE_JIT_FPU\n");
+ comprintf("\tuae_u16 extra=%s;\n", gen_nextiword());
+ swap_opcode();
+ comprintf("\tcomp_fpp_opp(opcode,extra);\n");
+ comprintf("#else\n");
+ comprintf("\tfailure = 1;\n");
+ comprintf("#endif\n");
+ break;
- case i_FBcc:
+ case i_FBcc:
#ifdef DISABLE_I_FBCC
- failure;
+ failure;
#endif
- uses_fpu;
- isjump;
- uses_cmov;
- mayfail;
- comprintf("#ifdef USE_JIT_FPU\n");
- swap_opcode();
- comprintf("\tcomp_fbcc_opp(opcode);\n");
- comprintf("#else\n");
- comprintf("\tfailure = 1;\n");
- comprintf("#endif\n");
- break;
+ uses_fpu;
+ isjump;
+ uses_cmov;
+ mayfail;
+ comprintf("#ifdef USE_JIT_FPU\n");
+ swap_opcode();
+ comprintf("\tcomp_fbcc_opp(opcode);\n");
+ comprintf("#else\n");
+ comprintf("\tfailure = 1;\n");
+ comprintf("#endif\n");
+ break;
- case i_FDBcc:
- uses_fpu;
- isjump;
- failure;
- break;
+ case i_FDBcc:
+ uses_fpu;
+ isjump;
+ failure;
+ break;
- case i_FScc:
+ case i_FScc:
#ifdef DISABLE_I_FSCC
- failure;
+ failure;
#endif
- uses_fpu;
- mayfail;
- uses_cmov;
- comprintf("#ifdef USE_JIT_FPU\n");
- comprintf("\tuae_u16 extra=%s;\n",gen_nextiword());
- swap_opcode();
- comprintf("\tcomp_fscc_opp(opcode,extra);\n");
- comprintf("#else\n");
- comprintf("\tfailure = 1;\n");
- comprintf("#endif\n");
- break;
+ uses_fpu;
+ mayfail;
+ uses_cmov;
+ comprintf("#ifdef USE_JIT_FPU\n");
+ comprintf("\tuae_u16 extra=%s;\n", gen_nextiword());
+ swap_opcode();
+ comprintf("\tcomp_fscc_opp(opcode,extra);\n");
+ comprintf("#else\n");
+ comprintf("\tfailure = 1;\n");
+ comprintf("#endif\n");
+ break;
- case i_FTRAPcc:
- uses_fpu;
- isjump;
- failure;
- break;
+ case i_FTRAPcc:
+ uses_fpu;
+ isjump;
+ failure;
+ break;
- case i_FSAVE:
- uses_fpu;
- failure;
- break;
+ case i_FSAVE:
+ uses_fpu;
+ failure;
+ break;
- case i_FRESTORE:
- uses_fpu;
- failure;
- break;
+ case i_FRESTORE:
+ uses_fpu;
+ failure;
+ break;
- case i_CINVL:
- case i_CINVP:
- case i_CINVA:
- isjump; /* Not really, but it's probably a good idea to stop
- translating at this point */
- failure;
- comprintf ("\tflush_icache();\n"); /* Differentiate a bit more? */
- break;
+ case i_CINVL:
+ case i_CINVP:
+ case i_CINVA:
+ isjump; /* Not really, but it's probably a good idea to stop
+ translating at this point */
+ failure;
+ comprintf("\tflush_icache();\n"); /* Differentiate a bit more? */
+ break;
- case i_CPUSHL:
- case i_CPUSHP:
- case i_CPUSHA:
- isjump; /* Not really, but it's probably a good idea to stop
- translating at this point */
- failure;
- break;
+ case i_CPUSHL:
+ case i_CPUSHP:
+ case i_CPUSHA:
+ isjump; /* Not really, but it's probably a good idea to stop
+ translating at this point */
+ failure;
+ break;
- case i_MOVE16:
+ case i_MOVE16:
#ifdef DISABLE_I_MOVE16
- failure;
+ failure;
#endif
- genmov16(opcode,curi);
- break;
+ genmov16(opcode, curi);
+ break;
#ifdef UAE
- case i_MMUOP030:
- case i_PFLUSHN:
- case i_PFLUSH:
- case i_PFLUSHAN:
- case i_PFLUSHA:
- case i_PLPAR:
- case i_PLPAW:
- case i_PTESTR:
- case i_PTESTW:
- case i_LPSTOP:
- case i_HALT:
- case i_PULSE:
- isjump;
- failure;
- break;
+ case i_MMUOP030:
+ case i_PFLUSHN:
+ case i_PFLUSH:
+ case i_PFLUSHAN:
+ case i_PFLUSHA:
+ case i_PLPAR:
+ case i_PLPAW:
+ case i_PTESTR:
+ case i_PTESTW:
+ case i_LPSTOP:
+ case i_PULSE:
+ case i_HALT:
+ isjump;
+ failure;
+ break;
#endif
#ifdef WINUAE_ARANYM
- case i_EMULOP_RETURN:
- isjump;
- failure;
- break;
-
- case i_EMULOP:
- failure;
- break;
+ case i_EMULOP_RETURN:
+ isjump;
+ failure;
+ break;
- case i_NATFEAT_ID:
- case i_NATFEAT_CALL:
- failure;
- break;
+ case i_EMULOP:
+ failure;
+ break;
- case i_MMUOP:
- isjump;
- failure;
- break;
+ case i_NATFEAT_ID:
+ case i_NATFEAT_CALL:
+ failure;
+ break;
+
+ case i_MMUOP:
+ isjump;
+ failure;
+ break;
#endif
- default:
+ default:
assert(0);
- break;
- }
- comprintf("%s",endstr);
- finish_braces ();
- sync_m68k_pc ();
- if (global_mayfail)
- comprintf("\tif (failure) m68k_pc_offset=m68k_pc_offset_thisinst;\n");
- return global_failure;
+ break;
+ }
+ comprintf("%s", endstr);
+ finish_braces();
+ sync_m68k_pc();
+ if (global_mayfail) {
+ comprintf("if (failure) {\n");
+ comprintf("m68k_pc_offset = m68k_pc_offset_thisinst;\n");
+ comprintf("}\n");
+ }
+ return global_failure;
}
static void
-generate_includes (FILE * f)
+generate_includes(FILE *f)
{
- fprintf (f, "#include \"sysconfig.h\"\n");
- fprintf (f, "#if defined(JIT)\n");
- fprintf (f, "#include \"sysdeps.h\"\n");
+ fprintf(f, "#include \"sysconfig.h\"\n");
+ fprintf(f, "#if defined(JIT)\n");
+ fprintf(f, "#include \"sysdeps.h\"\n");
#ifdef UAE
- fprintf (f, "#include \"options.h\"\n");
- fprintf (f, "#include \"memory.h\"\n");
+ fprintf(f, "#include \"options.h\"\n");
+ fprintf(f, "#include \"uae/memory.h\"\n");
#else
- fprintf (f, "#include \"m68k.h\"\n");
- fprintf (f, "#include \"memory-uae.h\"\n");
+ fprintf(f, "#include \"m68k.h\"\n");
+ fprintf(f, "#include \"memory-uae.h\"\n");
#endif
- fprintf (f, "#include \"readcpu.h\"\n");
- fprintf (f, "#include \"newcpu.h\"\n");
- fprintf (f, "#include \"comptbl.h\"\n");
- fprintf (f, "#include \"debug.h\"\n");
+ fprintf(f, "#include \"readcpu.h\"\n");
+ fprintf(f, "#include \"newcpu.h\"\n");
+ fprintf(f, "#include \"comptbl.h\"\n");
+ fprintf(f, "#include \"debug.h\"\n");
}
static int postfix;
-#ifdef UAE
-static char *decodeEA (amodes mode, wordsizes size)
+static char *decodeEA(amodes mode, wordsizes size)
{
static char buffer[80];
buffer[0] = 0;
- switch (mode){
+ switch (mode) {
case Dreg:
- strcpy (buffer,"Dn");
+ strcpy(buffer, "Dn");
break;
case Areg:
- strcpy (buffer,"An");
+ strcpy(buffer, "An");
break;
case Aind:
- strcpy (buffer,"(An)");
+ strcpy(buffer, "(An)");
break;
case Aipi:
- strcpy (buffer,"(An)+");
+ strcpy(buffer, "(An)+");
break;
case Apdi:
- strcpy (buffer,"-(An)");
+ strcpy(buffer, "-(An)");
break;
case Ad16:
- strcpy (buffer,"(d16,An)");
+ strcpy(buffer, "(d16,An)");
break;
case Ad8r:
- strcpy (buffer,"(d8,An,Xn)");
+ strcpy(buffer, "(d8,An,Xn)");
break;
case PC16:
- strcpy (buffer,"(d16,PC)");
+ strcpy(buffer, "(d16,PC)");
break;
case PC8r:
- strcpy (buffer,"(d8,PC,Xn)");
+ strcpy(buffer, "(d8,PC,Xn)");
break;
case absw:
- strcpy (buffer,"(xxx).W");
+ strcpy(buffer, "(xxx).W");
break;
case absl:
- strcpy (buffer,"(xxx).L");
+ strcpy(buffer, "(xxx).L");
break;
case imm:
- switch (size){
+ switch (size) {
case sz_byte:
- strcpy (buffer,"#<data>.B");
+ strcpy(buffer, "#<data>.B");
break;
case sz_word:
- strcpy (buffer,"#<data>.W");
+ strcpy(buffer, "#<data>.W");
break;
case sz_long:
- strcpy (buffer,"#<data>.L");
+ strcpy(buffer, "#<data>.L");
break;
default:
break;
}
break;
case imm0:
- strcpy (buffer,"#<data>.B");
+ strcpy(buffer, "#<data>.B");
break;
case imm1:
- strcpy (buffer,"#<data>.W");
+ strcpy(buffer, "#<data>.W");
break;
case imm2:
- strcpy (buffer,"#<data>.L");
+ strcpy(buffer, "#<data>.L");
break;
case immi:
- strcpy (buffer,"#<data>");
+ strcpy(buffer, "#<data>");
break;
default:
return buffer;
}
-static char *outopcode (int opcode)
+static char *outopcode(const char *name, int opcode)
{
static char out[100];
struct instr *ins;
- int i;
ins = &table68k[opcode];
- for (i = 0; lookuptab[i].name[0]; i++) {
- if (ins->mnemo == lookuptab[i].mnemo)
- break;
- }
- {
- char *s = ua (lookuptab[i].name);
- strcpy (out, s);
- xfree (s);
- }
+ strcpy(out, name);
if (ins->smode == immi)
- strcat (out, "Q");
+ strcat(out, "Q");
if (ins->size == sz_byte)
- strcat (out,".B");
+ strcat(out, ".B");
if (ins->size == sz_word)
- strcat (out,".W");
+ strcat(out, ".W");
if (ins->size == sz_long)
- strcat (out,".L");
- strcat (out," ");
+ strcat(out, ".L");
+ strcat(out, " ");
if (ins->suse)
- strcat (out, decodeEA (ins->smode, ins->size));
+ strcat(out, decodeEA(ins->smode, ins->size));
if (ins->duse) {
- if (ins->suse) strcat (out,",");
- strcat (out, decodeEA (ins->dmode, ins->size));
+ if (ins->suse) strcat(out, ",");
+ strcat(out, decodeEA(ins->dmode, ins->size));
}
return out;
}
-#endif
static void
-generate_one_opcode (int rp, int noflags)
+generate_one_opcode(int rp, int noflags)
{
- int i;
- uae_u16 smsk, dmsk;
- unsigned int opcode = opcode_map[rp];
- int aborted=0;
- int have_srcreg=0;
- int have_dstreg=0;
-#ifdef UAE
- char *name;
-#else
+ int i;
+ uae_u16 smsk, dmsk;
+ unsigned int opcode = opcode_map[rp];
+ int aborted = 0;
+ int have_srcreg = 0;
+ int have_dstreg = 0;
const char *name;
-#endif
+ const char *tbl = noflags ? "nf" : "ff";
- if (table68k[opcode].mnemo == i_ILLG
- || table68k[opcode].clev > cpu_level)
- return;
+ if (table68k[opcode].mnemo == i_ILLG
+ || table68k[opcode].clev > cpu_level)
+ return;
- for (i = 0; lookuptab[i].name[0]; i++)
- {
- if (table68k[opcode].mnemo == lookuptab[i].mnemo)
- break;
- }
+ for (i = 0; lookuptab[i].name[0]; i++)
+ {
+ if (table68k[opcode].mnemo == lookuptab[i].mnemo)
+ break;
+ }
- if (table68k[opcode].handler != -1)
- return;
+ if (table68k[opcode].handler != -1)
+ return;
- switch (table68k[opcode].stype)
- {
- case 0:
- smsk = 7;
- break;
- case 1:
- smsk = 255;
- break;
- case 2:
- smsk = 15;
- break;
- case 3:
- smsk = 7;
- break;
- case 4:
- smsk = 7;
- break;
- case 5:
- smsk = 63;
- break;
+ name = ua(lookuptab[i].name);
+ comprintf("/* %s */\n", outopcode(name, opcode));
+ comprintf(RETTYPE " REGPARAM2 op_%x_%d_comp_%s(uae_u32 opcode) /* %s */\n{\n", opcode, postfix, tbl, name);
+
+ switch (table68k[opcode].stype)
+ {
+ case 0:
+ smsk = 7;
+ break;
+ case 1:
+ smsk = 255;
+ break;
+ case 2:
+ smsk = 15;
+ break;
+ case 3:
+ smsk = 7;
+ break;
+ case 4:
+ smsk = 7;
+ break;
+ case 5:
+ smsk = 63;
+ break;
#ifndef UAE
- case 6:
- smsk = 255;
- break;
+ case 6:
+ smsk = 255;
+ break;
#endif
case 7:
- smsk = 3;
- break;
- default:
- assert(0);
- }
- dmsk = 7;
-
- next_cpu_level = -1;
- if (table68k[opcode].suse
- && table68k[opcode].smode != imm && table68k[opcode].smode != imm0
- && table68k[opcode].smode != imm1 && table68k[opcode].smode != imm2
- && table68k[opcode].smode != absw && table68k[opcode].smode != absl
- && table68k[opcode].smode != PC8r && table68k[opcode].smode != PC16)
- {
- have_srcreg=1;
- if (table68k[opcode].spos == -1)
- {
- if (((int) table68k[opcode].sreg) >= 128)
- comprintf ("\tuae_s32 srcreg = (uae_s32)(uae_s8)%d;\n", (int) table68k[opcode].sreg);
- else
- comprintf ("\tuae_s32 srcreg = %d;\n", (int) table68k[opcode].sreg);
+ smsk = 3;
+ break;
+ default:
+ smsk = 0;
+ assert(0);
}
- else
- {
- char source[100];
- int pos = table68k[opcode].spos;
+ dmsk = 7;
-#ifndef UAE
- comprintf ("#if defined(HAVE_GET_WORD_UNSWAPPED) && !defined(FULLMMU)\n");
-
- if (pos < 8 && (smsk >> (8 - pos)) != 0)
- sprintf (source, "(((opcode >> %d) | (opcode << %d)) & %d)",
- pos ^ 8, 8 - pos, dmsk);
- else if (pos != 8)
- sprintf (source, "((opcode >> %d) & %d)", pos ^ 8, smsk);
- else
- sprintf (source, "(opcode & %d)", smsk);
-
- if (table68k[opcode].stype == 3)
- comprintf ("\tuae_u32 srcreg = imm8_table[%s];\n", source);
- else if (table68k[opcode].stype == 1)
- comprintf ("\tuae_u32 srcreg = (uae_s32)(uae_s8)%s;\n", source);
- else
- comprintf ("\tuae_u32 srcreg = %s;\n", source);
-
- comprintf ("#else\n");
-#endif
-
- if (pos)
- sprintf (source, "((opcode >> %d) & %d)", pos, smsk);
- else
- sprintf (source, "(opcode & %d)", smsk);
-
- if (table68k[opcode].stype == 3)
- comprintf ("\tuae_s32 srcreg = imm8_table[%s];\n", source);
- else if (table68k[opcode].stype == 1)
- comprintf ("\tuae_s32 srcreg = (uae_s32)(uae_s8)%s;\n", source);
- else
- comprintf ("\tuae_s32 srcreg = %s;\n", source);
+ next_cpu_level = -1;
+ if (table68k[opcode].suse
+ && table68k[opcode].smode != imm && table68k[opcode].smode != imm0
+ && table68k[opcode].smode != imm1 && table68k[opcode].smode != imm2
+ && table68k[opcode].smode != absw && table68k[opcode].smode != absl
+ && table68k[opcode].smode != PC8r && table68k[opcode].smode != PC16)
+ {
+ have_srcreg = 1;
+ if (table68k[opcode].spos == -1)
+ {
+ if (((int)table68k[opcode].sreg) >= 128)
+ comprintf("\tuae_s32 srcreg = (uae_s32)(uae_s8)%d;\n", (int)table68k[opcode].sreg);
+ else
+ comprintf("\tuae_s32 srcreg = %d;\n", (int)table68k[opcode].sreg);
+ } else
+ {
+ char source[100];
+ int pos = table68k[opcode].spos;
#ifndef UAE
- comprintf ("#endif\n");
-#endif
- }
- }
- if (table68k[opcode].duse
- /* Yes, the dmode can be imm, in case of LINK or DBcc */
- && table68k[opcode].dmode != imm && table68k[opcode].dmode != imm0
- && table68k[opcode].dmode != imm1 && table68k[opcode].dmode != imm2
- && table68k[opcode].dmode != absw && table68k[opcode].dmode != absl)
- {
- have_dstreg=1;
- if (table68k[opcode].dpos == -1)
- {
- if (((int) table68k[opcode].dreg) >= 128)
- comprintf ("\tuae_s32 dstreg = (uae_s32)(uae_s8)%d;\n", (int) table68k[opcode].dreg);
- else
- comprintf ("\tuae_s32 dstreg = %d;\n", (int) table68k[opcode].dreg);
+ comprintf("#if defined(HAVE_GET_WORD_UNSWAPPED) && !defined(FULLMMU)\n");
+#else
+ comprintf("#if defined(HAVE_GET_WORD_UNSWAPPED)\n");
+#endif
+
+ if (pos < 8 && (smsk >> (8 - pos)) != 0)
+ sprintf(source, "(((opcode >> %d) | (opcode << %d)) & %d)",
+ pos ^ 8, 8 - pos, dmsk);
+ else if (pos != 8)
+ sprintf(source, "((opcode >> %d) & %d)", pos ^ 8, smsk);
+ else
+ sprintf(source, "(opcode & %d)", smsk);
+
+ if (table68k[opcode].stype == 3)
+ comprintf("\tuae_u32 srcreg = imm8_table[%s];\n", source);
+ else if (table68k[opcode].stype == 1)
+ comprintf("\tuae_u32 srcreg = (uae_s32)(uae_s8)%s;\n", source);
+ else
+ comprintf("\tuae_u32 srcreg = %s;\n", source);
+
+ comprintf("#else\n");
+
+ if (pos)
+ sprintf(source, "((opcode >> %d) & %d)", pos, smsk);
+ else
+ sprintf(source, "(opcode & %d)", smsk);
+
+ if (table68k[opcode].stype == 3)
+ comprintf("\tuae_s32 srcreg = imm8_table[%s];\n", source);
+ else if (table68k[opcode].stype == 1)
+ comprintf("\tuae_s32 srcreg = (uae_s32)(uae_s8)%s;\n", source);
+ else
+ comprintf("\tuae_s32 srcreg = %s;\n", source);
+
+ comprintf("#endif\n");
+ }
}
- else
+ if (table68k[opcode].duse
+ /* Yes, the dmode can be imm, in case of LINK or DBcc */
+ && table68k[opcode].dmode != imm && table68k[opcode].dmode != imm0
+ && table68k[opcode].dmode != imm1 && table68k[opcode].dmode != imm2
+ && table68k[opcode].dmode != absw && table68k[opcode].dmode != absl)
{
- int pos = table68k[opcode].dpos;
+ have_dstreg = 1;
+ if (table68k[opcode].dpos == -1)
+ {
+ if (((int)table68k[opcode].dreg) >= 128)
+ comprintf("\tuae_s32 dstreg = (uae_s32)(uae_s8)%d;\n", (int)table68k[opcode].dreg);
+ else
+ comprintf("\tuae_s32 dstreg = %d;\n", (int)table68k[opcode].dreg);
+ } else
+ {
+ int pos = table68k[opcode].dpos;
#ifndef UAE
- comprintf ("#if defined(HAVE_GET_WORD_UNSWAPPED) && !defined(FULLMMU)\n");
-
- if (pos < 8 && (dmsk >> (8 - pos)) != 0)
- comprintf ("\tuae_u32 dstreg = ((opcode >> %d) | (opcode << %d)) & %d;\n",
- pos ^ 8, 8 - pos, dmsk);
- else if (pos != 8)
- comprintf ("\tuae_u32 dstreg = (opcode >> %d) & %d;\n",
- pos ^ 8, dmsk);
- else
- comprintf ("\tuae_u32 dstreg = opcode & %d;\n", dmsk);
-
- comprintf ("#else\n");
-#endif
-
- if (pos)
- comprintf ("\tuae_u32 dstreg = (opcode >> %d) & %d;\n",
- pos, dmsk);
- else
- comprintf ("\tuae_u32 dstreg = opcode & %d;\n", dmsk);
+ comprintf("#if defined(HAVE_GET_WORD_UNSWAPPED) && !defined(FULLMMU)\n");
-#ifndef UAE
- comprintf ("#endif\n");
-#endif
- }
- }
-
- if (have_srcreg && have_dstreg &&
- (table68k[opcode].dmode==Areg ||
- table68k[opcode].dmode==Aind ||
- table68k[opcode].dmode==Aipi ||
- table68k[opcode].dmode==Apdi ||
- table68k[opcode].dmode==Ad16 ||
- table68k[opcode].dmode==Ad8r) &&
- (table68k[opcode].smode==Areg ||
- table68k[opcode].smode==Aind ||
- table68k[opcode].smode==Aipi ||
- table68k[opcode].smode==Apdi ||
- table68k[opcode].smode==Ad16 ||
- table68k[opcode].smode==Ad8r)
- ) {
- comprintf("\tuae_u32 dodgy=(srcreg==(uae_s32)dstreg);\n");
- }
- else {
- comprintf("\tuae_u32 dodgy=0;\n");
- }
- comprintf("\tuae_u32 m68k_pc_offset_thisinst=m68k_pc_offset;\n");
- comprintf("\tm68k_pc_offset+=2;\n");
-
- aborted=gen_opcode (opcode);
- {
- char flags[64 * 6];
- *flags = '\0';
- if (global_isjump) strcat(flags, "COMP_OPCODE_ISJUMP|");
- if (long_opcode) strcat(flags, "COMP_OPCODE_LONG_OPCODE|");
- if (global_cmov) strcat(flags, "COMP_OPCODE_CMOV|");
- if (global_isaddx) strcat(flags, "COMP_OPCODE_ISADDX|");
- if (global_iscjump) strcat(flags, "COMP_OPCODE_ISCJUMP|");
- if (global_fpu) strcat(flags, "COMP_OPCODE_USES_FPU|");
- if (*flags)
- flags[strlen(flags) - 1] = '\0';
- else
- strcpy(flags, "0");
+ if (pos < 8 && (dmsk >> (8 - pos)) != 0)
+ comprintf("\tuae_u32 dstreg = ((opcode >> %d) | (opcode << %d)) & %d;\n",
+ pos ^ 8, 8 - pos, dmsk);
+ else if (pos != 8)
+ comprintf("\tuae_u32 dstreg = (opcode >> %d) & %d;\n",
+ pos ^ 8, dmsk);
+ else
+ comprintf("\tuae_u32 dstreg = opcode & %d;\n", dmsk);
-#ifdef UAE
- comprintf ("return 0;\n");
+ comprintf("#else\n");
#endif
- comprintf ("}\n");
-#ifdef UAE
- name = ua (lookuptab[i].name);
-#else
- name = lookuptab[i].name;
+ if (pos)
+ comprintf("\tuae_u32 dstreg = (opcode >> %d) & %d;\n",
+ pos, dmsk);
+ else
+ comprintf("\tuae_u32 dstreg = opcode & %d;\n", dmsk);
+
+#ifndef UAE
+ comprintf("#endif\n");
#endif
- if (aborted) {
- fprintf (stblfile, "{ NULL, %u, %s }, /* %s */\n", opcode, flags, name);
- com_discard();
+ }
+ }
+
+ if (have_srcreg && have_dstreg &&
+ (table68k[opcode].dmode == Areg ||
+ table68k[opcode].dmode == Aind ||
+ table68k[opcode].dmode == Aipi ||
+ table68k[opcode].dmode == Apdi ||
+ table68k[opcode].dmode == Ad16 ||
+ table68k[opcode].dmode == Ad8r) &&
+ (table68k[opcode].smode == Areg ||
+ table68k[opcode].smode == Aind ||
+ table68k[opcode].smode == Aipi ||
+ table68k[opcode].smode == Apdi ||
+ table68k[opcode].smode == Ad16 ||
+ table68k[opcode].smode == Ad8r)
+ ) {
+ comprintf("\tuae_u32 dodgy=(srcreg==(uae_s32)dstreg);\n");
} else {
- const char *tbl = noflags ? "nf" : "ff";
-#ifdef UAE
- printf ("/* %s */\n", outopcode (opcode));
-#else
- printf ("/* %s */\n", name);
-#endif
- fprintf (stblfile, "{ op_%x_%d_comp_%s, %u, %s }, /* %s */\n", opcode, postfix, tbl, opcode, flags, name);
- fprintf (headerfile, "extern compop_func op_%x_%d_comp_%s;\n", opcode, postfix, tbl);
- printf (RETTYPE " REGPARAM2 op_%x_%d_comp_%s(uae_u32 opcode)\n{\n", opcode, postfix, tbl);
- com_flush();
+ comprintf("\tuae_u32 dodgy=0;\n");
}
-#ifdef UAE
- xfree (name);
-#endif
- }
- opcode_next_clev[rp] = next_cpu_level;
- opcode_last_postfix[rp] = postfix;
+ comprintf("\tuae_u32 m68k_pc_offset_thisinst=m68k_pc_offset;\n");
+ comprintf("\tm68k_pc_offset+=2;\n");
+
+ aborted = gen_opcode(opcode);
+ {
+ char flags[64 * 6];
+ *flags = '\0';
+ if (global_isjump) strcat(flags, "COMP_OPCODE_ISJUMP|");
+ if (long_opcode) strcat(flags, "COMP_OPCODE_LONG_OPCODE|");
+ if (global_cmov) strcat(flags, "COMP_OPCODE_CMOV|");
+ if (global_isaddx) strcat(flags, "COMP_OPCODE_ISADDX|");
+ if (global_iscjump) strcat(flags, "COMP_OPCODE_ISCJUMP|");
+ if (global_fpu) strcat(flags, "COMP_OPCODE_USES_FPU|");
+ if (*flags)
+ flags[strlen(flags) - 1] = '\0';
+ else
+ strcpy(flags, "0");
+
+#ifdef UAE /* RETTYPE != void */
+ comprintf("return 0;\n");
+#endif
+ comprintf("}\n");
+
+ if (aborted) {
+ fprintf(stblfile, "{ NULL, %u, %s }, /* %s */\n", opcode, flags, name);
+ com_discard();
+ } else {
+ fprintf(stblfile, "{ op_%x_%d_comp_%s, %u, %s }, /* %s */\n", opcode, postfix, tbl, opcode, flags, name);
+ fprintf(headerfile, "extern compop_func op_%x_%d_comp_%s;\n", opcode, postfix, tbl);
+ com_flush();
+ }
+ }
+ opcode_next_clev[rp] = next_cpu_level;
+ opcode_last_postfix[rp] = postfix;
}
static void
-generate_func (int noflags)
+generate_func(int noflags)
{
- int i, j, rp;
+ int i, j, rp;
const char *tbl = noflags ? "nf" : "ff";
- using_prefetch = 0;
- using_exception_3 = 0;
- for (i = 0; i < 1; i++) /* We only do one level! */
- {
- cpu_level = NEXT_CPU_LEVEL - i;
- postfix = i;
-
- fprintf (stblfile, "const struct comptbl op_smalltbl_%d_comp_%s[] = {\n", postfix, tbl);
-
- /* sam: this is for people with low memory (eg. me :)) */
- printf ("\n"
- "#if !defined(PART_1) && !defined(PART_2) && "
- "!defined(PART_3) && !defined(PART_4) && "
- "!defined(PART_5) && !defined(PART_6) && "
- "!defined(PART_7) && !defined(PART_8)"
- "\n"
- "#define PART_1 1\n"
- "#define PART_2 1\n"
- "#define PART_3 1\n"
- "#define PART_4 1\n"
- "#define PART_5 1\n"
- "#define PART_6 1\n"
- "#define PART_7 1\n"
- "#define PART_8 1\n"
- "#endif\n\n");
+ using_prefetch = 0;
+ using_exception_3 = 0;
+ for (i = 0; i < 1; i++) /* We only do one level! */
+ {
+ cpu_level = NEXT_CPU_LEVEL - i;
+ postfix = i;
+
+ fprintf(stblfile, "const struct comptbl op_smalltbl_%d_comp_%s[] = {\n", postfix, tbl);
+
+ /* sam: this is for people with low memory (eg. me :)) */
+ printf("\n"
+ "#if !defined(PART_1) && !defined(PART_2) && "
+ "!defined(PART_3) && !defined(PART_4) && "
+ "!defined(PART_5) && !defined(PART_6) && "
+ "!defined(PART_7) && !defined(PART_8)"
+ "\n"
+ "#define PART_1 1\n"
+ "#define PART_2 1\n"
+ "#define PART_3 1\n"
+ "#define PART_4 1\n"
+ "#define PART_5 1\n"
+ "#define PART_6 1\n"
+ "#define PART_7 1\n"
+ "#define PART_8 1\n"
+ "#endif\n\n");
#ifdef UAE
- printf ("extern void comp_fpp_opp();\n"
- "extern void comp_fscc_opp();\n"
- "extern void comp_fbcc_opp();\n\n");
+
+ printf("#ifdef USE_JIT_FPU\n");
+ printf("extern void comp_fpp_opp();\n"
+ "extern void comp_fscc_opp();\n"
+ "extern void comp_fbcc_opp();\n");
+ printf("#endif\n");
+ printf("\n");
#endif
- rp = 0;
- for (j = 1; j <= 8; ++j)
- {
- int k = (j * nr_cpuop_funcs) / 8;
- printf ("#ifdef PART_%d\n", j);
- for (; rp < k; rp++)
- generate_one_opcode (rp,noflags);
- printf ("#endif\n\n");
+ rp = 0;
+ for (j = 1; j <= 8; ++j)
+ {
+ int k = (j * nr_cpuop_funcs) / 8;
+ printf("#ifdef PART_%d\n", j);
+ for (; rp < k; rp++)
+ generate_one_opcode(rp, noflags);
+ printf("#endif\n\n");
+ }
+
+ fprintf(stblfile, "{ 0, 65536, 0 }};\n");
}
- fprintf (stblfile, "{ 0, 65536, 0 }};\n");
- }
+}
+#if (defined(OS_cygwin) || defined(OS_mingw)) && defined(EXTENDED_SIGSEGV)
+void cygwin_mingw_abort()
+{
+#undef abort
+ abort();
}
+#endif
-#ifdef __cplusplus
-int main(int, char **)
+#if defined(FSUAE) && defined (WINDOWS)
+#include "windows.h"
+int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
#else
-int main()
+int main(void)
#endif
{
- read_table68k ();
- do_merges ();
+ init_table68k();
- opcode_map = (int *) malloc (sizeof (int) * nr_cpuop_funcs);
- opcode_last_postfix = (int *) malloc (sizeof (int) * nr_cpuop_funcs);
- opcode_next_clev = (int *) malloc (sizeof (int) * nr_cpuop_funcs);
- counts = (unsigned long *) malloc (65536 * sizeof (unsigned long));
- read_counts ();
+ opcode_map = (int *)malloc(sizeof(int) * nr_cpuop_funcs);
+ opcode_last_postfix = (int *)malloc(sizeof(int) * nr_cpuop_funcs);
+ opcode_next_clev = (int *)malloc(sizeof(int) * nr_cpuop_funcs);
+ counts = (unsigned long *)malloc(65536 * sizeof(unsigned long));
+ read_counts();
- /* It would be a lot nicer to put all in one file (we'd also get rid of
- * cputbl.h that way), but cpuopti can't cope. That could be fixed, but
- * I don't dare to touch the 68k version. */
+ /* It would be a lot nicer to put all in one file (we'd also get rid of
+ * cputbl.h that way), but cpuopti can't cope. That could be fixed, but
+ * I don't dare to touch the 68k version. */
- headerfile = fopen (GEN_PATH "comptbl.h", "wb");
- fprintf (headerfile, ""
+ headerfile = fopen(GEN_PATH "comptbl.h", "wb");
+ fprintf(headerfile, ""
"extern const struct comptbl op_smalltbl_0_comp_nf[];\n"
"extern const struct comptbl op_smalltbl_0_comp_ff[];\n"
"");
- stblfile = fopen (GEN_PATH "compstbl.cpp", "wb");
- if (freopen (GEN_PATH "compemu.cpp", "wb", stdout) == NULL) {
+ stblfile = fopen(GEN_PATH "compstbl.cpp", "wb");
+ if (freopen(GEN_PATH "compemu.cpp", "wb", stdout) == NULL) {
abort();
}
- generate_includes (stdout);
- generate_includes (stblfile);
+ generate_includes(stdout);
+ generate_includes(stblfile);
- printf("#include \"" JIT_PATH "compemu.h\"\n");
+ printf("#include \"" JIT_PATH "compemu.h\"\n");
+ printf("#include \"" JIT_PATH "flags_x86.h\"\n");
- noflags=0;
- generate_func (noflags);
+ noflags = 0;
+ generate_func(noflags);
free(opcode_map);
free(opcode_last_postfix);
free(opcode_next_clev);
free(counts);
- opcode_map = (int *) malloc (sizeof (int) * nr_cpuop_funcs);
- opcode_last_postfix = (int *) malloc (sizeof (int) * nr_cpuop_funcs);
- opcode_next_clev = (int *) malloc (sizeof (int) * nr_cpuop_funcs);
- counts = (unsigned long *) malloc (65536 * sizeof (unsigned long));
- read_counts ();
- noflags=1;
- generate_func (noflags);
+ opcode_map = (int *)malloc(sizeof(int) * nr_cpuop_funcs);
+ opcode_last_postfix = (int *)malloc(sizeof(int) * nr_cpuop_funcs);
+ opcode_next_clev = (int *)malloc(sizeof(int) * nr_cpuop_funcs);
+ counts = (unsigned long *)malloc(65536 * sizeof(unsigned long));
+ read_counts();
+ noflags = 1;
+ generate_func(noflags);
- printf ("#endif\n");
- fprintf (stblfile, "#endif\n");
+ printf("#endif\n");
+ fprintf(stblfile, "#endif\n");
free(opcode_map);
free(opcode_last_postfix);
free(opcode_next_clev);
free(counts);
- free (table68k);
- fclose (stblfile);
- fclose (headerfile);
- return 0;
+ free(table68k);
+ fclose(stblfile);
+ fclose(headerfile);
+ (void)disasm_this_inst;
+ return 0;
}
#ifdef UAE
-void write_log (const TCHAR *format,...)
+void write_log(const TCHAR *format, ...)
{
}
#endif
--- /dev/null
+#include "options.h"
+#include "memory.h"
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)
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);
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];
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];
{
}
+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;
}
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)
} else {
mode = 1;
m68k_pc_indirect = 0;
+ jit = 1;
if (currprefs.comptrustbyte) {
mode = 2;
m68k_pc_indirect = -1;
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];
/* 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];
}
}
+
+ 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);
}
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) {
}
#endif
- read_table68k ();
- do_merges ();
+ init_table68k();
write_log (_T("%d CPU functions\n"), nr_cpuop_funcs);
}
}
// 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;
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);
}
}
-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) {
}
}
}
-void REGPARAM2 Exception (int nr)
+void REGPARAM2 Exception_cpu(int nr)
+{
+ Exception_cpu_oldpc(nr, 0xffffffff);
+}
+void REGPARAM2 Exception(int nr)
{
- ExceptionX (nr, -1);
+ ExceptionX(nr, 0xffffffff, 0xffffffff);
}
-void REGPARAM2 ExceptionL (int nr, uaecptr address)
+void REGPARAM2 ExceptionL(int nr, uaecptr address)
{
- ExceptionX (nr, address);
+ ExceptionX(nr, address, 0xffffffff);
}
static void bus_error(void)
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?
}
}
+static uae_u32 get_jit_opcode(void)
+{
+ uae_u32 opcode;
+ if (currprefs.cpu_compatible) {
+ opcode = get_word_020_prefetchf(m68k_getpc());
+#ifdef HAVE_GET_WORD_UNSWAPPED
+ opcode = do_byteswap_16(opcode);
+#endif
+ } else {
+#ifdef HAVE_GET_WORD_UNSWAPPED
+ opcode = do_get_mem_word_unswapped((uae_u16 *)get_real_address(m68k_getpc()));
+#else
+ opcode = x_get_iword(0);
+#endif
+ }
+ return opcode;
+}
+
void exec_nostats (void)
{
struct regstruct *r = ®s;
for (;;)
{
- if (currprefs.cpu_compatible) {
- r->opcode = get_word_020_prefetchf(m68k_getpc());
- } else {
- r->opcode = x_get_iword(0);
- }
- cpu_cycles = (*cpufunctbl[r->opcode])(r->opcode) >> 16;
- cpu_cycles = adjust_cycles (cpu_cycles);
+ r->opcode = get_jit_opcode();
+
+ (*cpufunctbl[r->opcode])(r->opcode);
+
+ cpu_cycles = 4 * CYCLE_UNIT; // adjust_cycles(cpu_cycles);
if (!currprefs.cpu_thread) {
do_cycles (cpu_cycles);
}
}
-void execute_normal (void)
+void execute_normal(void)
{
struct regstruct *r = ®s;
int blocklen;
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) {
{
int lws;
uae_u32 tag;
- uae_u32 data;
struct cache030 *c;
regs.fc030 = (regs.s ? 4 : 0) | 2;
}
}
-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);
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);
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);
}
if (src == 0) {
- divsl_divbyzero(extra, a);
+ divsl_divbyzero(extra, a, oldpc);
return 0;
}
}
if (src == 0) {
- divul_divbyzero(extra, a);
+ divul_divbyzero(extra, a, oldpc);
return 0;
}
/*
* 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
/*
* 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)
#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
*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))
#define DRIVESOUND
#define GFXFILTER
#define X86_MSVC_ASSEMBLY
-#define OPTIMIZED_FLAGS
+//#define OPTIMIZED_FLAGS
#define MSVC_LONG_DOUBLE
#ifndef __i386__
#define __i386__
#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
{
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;
}
}
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++) {
/* parse the source address */
usesrc = 1;
+
switch (opcstr[pos++]) {
case 'D':
srcmode = Dreg;
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();
case 'a': srcmode = Aind; pos++; break;
}
break;
- case 'L':
- srcmode = absl;
- break;
case '#':
switch (opcstr[pos++]) {
case 'z': srcmode = imm; break;
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;
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;
table68k[opc].flaginfo[i].flaguse = id.flaginfo[i].flaguse;
}
#endif
- table68k[opc].flagdead = flagdead;
- table68k[opc].flaglive = flaglive;
- table68k[opc].isjmp = isjmp;
-nomatch:
- /* FOO! */;
- }
-}
+ // Fix flags used information for Scc, Bcc, TRAPcc, DBcc instructions
+ if (table68k[opc].mnemo == i_Scc
+ || table68k[opc].mnemo == i_Bcc
+ || table68k[opc].mnemo == i_DBcc
+ || table68k[opc].mnemo == i_TRAPcc
+ ) {
+ switch (table68k[opc].cc) {
+ // CC mask: XNZVC
+ // 8421
+ case 0: flags_used = 0x00; break; /* T */
+ case 1: flags_used = 0x00; break; /* F */
+ case 2: flags_used = 0x05; break; /* HI */
+ case 3: flags_used = 0x05; break; /* LS */
+ case 4: flags_used = 0x01; break; /* CC */
+ case 5: flags_used = 0x01; break; /* CS */
+ case 6: flags_used = 0x04; break; /* NE */
+ case 7: flags_used = 0x04; break; /* EQ */
+ case 8: flags_used = 0x02; break; /* VC */
+ case 9: flags_used = 0x02; break; /* VS */
+ case 10:flags_used = 0x08; break; /* PL */
+ case 11:flags_used = 0x08; break; /* MI */
+ case 12:flags_used = 0x0A; break; /* GE */
+ case 13:flags_used = 0x0A; break; /* LT */
+ case 14:flags_used = 0x0E; break; /* GT */
+ case 15:flags_used = 0x0E; break; /* LE */
+ }
+ }
-void read_table68k (void)
-{
- int i;
+#if 1
+ /* gb-- flagdead and flaglive would not have correct information */
+ table68k[opc].flagdead = flags_set;
+ table68k[opc].flaglive = flags_used;
+#else
+ table68k[opc].flagdead = flagdead;
+ table68k[opc].flaglive = flaglive;
+#endif
+ table68k[opc].cflow = cflow;
- free (table68k);
- table68k = xmalloc (struct instr, 65536);
- for (i = 0; i < 65536; i++) {
- table68k[i].mnemo = i_ILLG;
- table68k[i].handler = -1;
- }
- for (i = 0; i < n_defs68k; i++) {
- build_insn (i);
+ nomatch:
+ /* FOO! */;
}
}
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:
}
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;
+}
% C: condition codes, except F
% f: direction
% i: immediate
+% E: immediate, except 00 (Aranym only, EmulOp instruction)
% I: immediate, except 00 and ff
% j: immediate 1..8
% J: immediate 0..15
% 0 means flag reset
% 1 means flag set
% ? means programmer was too lazy to check or instruction may trap
-% + means instruction is conditional branch
-% everything else means flag set/used
-% / means instruction is unconditional branch/call
+% + means instruction is conditional branch (ignored, only for sync)
+% / means instruction is unconditional branch/call (ignored, only for sync)
% x means flag is unknown and well-behaved programs shouldn't check it
+% everything else means flag set/used
+%
+% Control flow
+% two letters, combination of
+% - nothing
+% T the instruction may trap or cause an exception
+% B branch instruction
+% J jump instruction
+% R return instruction
+%
% srcaddr status destaddr status :
% bitmasks of
% 1 means fetched
% 2 means stored
% 4 means jump offset
% 8 means jump address
+%
% instruction
% optional line feed and 68030 Head/Tail/Cycles/ea calculation
%
-0000 0000 0011 1100:000:XNZVC:XNZVC:10: ORSR.B #1
-0000 0000 0111 1100:002:?????:?????:10: ORSR.W #1
-0000 0zz0 11ss sSSS:250:?????:?????:11: CHK2.z #1,s[!Dreg,Areg,Aipi,Apdi,Immd]
+0000 0000 0011 1100:000:XNZVC:XNZVC:--:10: ORSR.B #1
+0000 0000 0111 1100:002:XNZVC:XNZVC:T-:10: ORSR.W #1
+0000 0zz0 11ss sSSS:250:-?Z?C:-----:T-:11: CHK2.z #1,s[!Dreg,Areg,Aipi,Apdi,Immd]
-0000 0000 zzdd dDDD:000:-NZ00:-----:13: OR.z #z,d[Dreg]
+0000 0000 zzdd dDDD:000:-NZ00:-----:--:13: OR.z #z,d[Dreg]
- 2 0 2 fiea
-0000 0000 zzdd dDDD:000:-NZ00:-----:13: OR.z #z,d[!Areg,Dreg]
+0000 0000 zzdd dDDD:000:-NZ00:-----:--:13: OR.z #z,d[!Areg,Dreg]
- 0 1 3 fiea
-0000 0010 0011 1100:000:XNZVC:XNZVC:10: ANDSR.B #1
-0000 0010 0111 1100:002:?????:?????:10: ANDSR.W #1
+0000 0010 0011 1100:000:XNZVC:XNZVC:--:10: ANDSR.B #1
+0000 0010 0111 1100:002:XNZVC:XNZVC:T-:10: ANDSR.W #1
-0000 0010 zzdd dDDD:000:-NZ00:-----:13: AND.z #z,d[Dreg]
+0000 0010 zzdd dDDD:000:-NZ00:-----:--:13: AND.z #z,d[Dreg]
- 2 0 2 fiea
-0000 0010 zzdd dDDD:000:-NZ00:-----:13: AND.z #z,d[!Areg,Dreg]
+0000 0010 zzdd dDDD:000:-NZ00:-----:--:13: AND.z #z,d[!Areg,Dreg]
- 0 1 3 fiea
-0000 0100 zzdd dDDD:000:XNZVC:-----:13: SUB.z #z,d[Dreg]
+0000 0100 zzdd dDDD:000:XNZVC:-----:--:13: SUB.z #z,d[Dreg]
- 2 0 2 fiea
-0000 0100 zzdd dDDD:000:XNZVC:-----:13: SUB.z #z,d[!Areg,Dreg]
+0000 0100 zzdd dDDD:000:XNZVC:-----:--:13: SUB.z #z,d[!Areg,Dreg]
- 0 1 3 fiea
-0000 0110 zzdd dDDD:000:XNZVC:-----:13: ADD.z #z,d[Dreg]
+0000 0110 zzdd dDDD:000:XNZVC:-----:--:13: ADD.z #z,d[Dreg]
- 2 0 2 fiea
-0000 0110 zzdd dDDD:000:XNZVC:-----:13: ADD.z #z,d[!Areg,Dreg]
+0000 0110 zzdd dDDD:000:XNZVC:-----:--:13: ADD.z #z,d[!Areg,Dreg]
- 0 1 3 fiea
-0000 0110 11ss sSSS:230:?????:?????:10: CALLM s[!Dreg,Areg,Aipi,Apdi,Immd]
-0000 0110 11ss sSSS:230:?????:?????:10: RTM s[Dreg,Areg]
+0000 0110 11ss sSSS:230:-----:XNZVC:--:10: CALLM s[!Dreg,Areg,Aipi,Apdi,Immd]
+0000 0110 11ss sSSS:230:XNZVC:-----:-R:10: RTM s[Dreg,Areg]
-0000 1000 00ss sSSS:000:--Z--:-----:11: BTST #1,s[Dreg]
+0000 1000 00ss sSSS:000:--Z--:-----:--:11: BTST #1,s[Dreg]
- 4 0 4
-0000 1000 00ss sSSS:000:--Z--:-----:11: BTST #1,s[!Areg,Dreg,Immd]
+0000 1000 00ss sSSS:000:--Z--:-----:--:11: BTST #1,s[!Areg,Dreg,Immd]
- 0 0 4 fiea
-0000 1000 01ss sSSS:000:--Z--:-----:13: BCHG #1,s[Dreg]
+0000 1000 01ss sSSS:000:--Z--:-----:--:13: BCHG #1,s[Dreg]
- 6 0 6
-0000 1000 01ss sSSS:000:--Z--:-----:13: BCHG #1,s[!Areg,Dreg,Immd,PC8r,PC16]
+0000 1000 01ss sSSS:000:--Z--:-----:--:13: BCHG #1,s[!Areg,Dreg,Immd,PC8r,PC16]
- 0 0 6 fiea
-0000 1000 10ss sSSS:000:--Z--:-----:13: BCLR #1,s[Dreg]
+0000 1000 10ss sSSS:000:--Z--:-----:--:13: BCLR #1,s[Dreg]
- 6 0 6
-0000 1000 10ss sSSS:000:--Z--:-----:13: BCLR #1,s[!Areg,Dreg,Immd,PC8r,PC16]
+0000 1000 10ss sSSS:000:--Z--:-----:--:13: BCLR #1,s[!Areg,Dreg,Immd,PC8r,PC16]
- 0 0 6 fiea
-0000 1000 11ss sSSS:000:--Z--:-----:13: BSET #1,s[Dreg]
+0000 1000 11ss sSSS:000:--Z--:-----:--:13: BSET #1,s[Dreg]
- 6 0 6
-0000 1000 11ss sSSS:000:--Z--:-----:13: BSET #1,s[!Areg,Dreg,Immd,PC8r,PC16]
+0000 1000 11ss sSSS:000:--Z--:-----:--:13: BSET #1,s[!Areg,Dreg,Immd,PC8r,PC16]
- 0 0 6 fiea
-0000 1010 0011 1100:000:XNZVC:XNZVC:10: EORSR.B #1
-0000 1010 0111 1100:002:?????:?????:10: EORSR.W #1
+0000 1010 0011 1100:000:XNZVC:XNZVC:--:10: EORSR.B #1
+0000 1010 0111 1100:002:XNZVC:XNZVC:T-:10: EORSR.W #1
-0000 1010 zzdd dDDD:000:-NZ00:-----:13: EOR.z #z,d[Dreg]
+0000 1010 zzdd dDDD:000:-NZ00:-----:--:13: EOR.z #z,d[Dreg]
- 2 0 2 fiea
-0000 1010 zzdd dDDD:000:-NZ00:-----:13: EOR.z #z,d[!Areg,Dreg]
+0000 1010 zzdd dDDD:000:-NZ00:-----:--:13: EOR.z #z,d[!Areg,Dreg]
- 0 1 3 fiea
-0000 1100 zzss sSSS:000:-NZVC:-----:11: CMP.z #z,s[Dreg]
+0000 1100 zzss sSSS:000:-NZVC:-----:--:11: CMP.z #z,s[Dreg]
- 2 0 2 fiea
-0000 1100 zzss sSSS:000:-NZVC:-----:11: CMP.z #z,s[!Areg,Dreg,Immd,PC8r,PC16]
+0000 1100 zzss sSSS:000:-NZVC:-----:--:11: CMP.z #z,s[!Areg,Dreg,Immd,PC8r,PC16]
- 0 0 2 fiea
-0000 1100 zzss sSSS:200:-NZVC:-----:11: CMP.z #z,s[PC8r,PC16]
+0000 1100 zzss sSSS:200:-NZVC:-----:--:11: CMP.z #z,s[PC8r,PC16]
- 0 0 2 fiea
-0000 1010 11ss sSSS:200:?????:?????:13: CAS.B #1,s[!Dreg,Areg,Immd,PC8r,PC16]
-0000 1100 11ss sSSS:200:?????:?????:13: CAS.W #1,s[!Dreg,Areg,Immd,PC8r,PC16]
-0000 1100 1111 1100:250:?????:?????:10: CAS2.W #2
-0000 1110 zzss sSSS:102:?????:?????:13: MOVES.z #1,s[!Dreg,Areg,Immd,PC8r,PC16]
-0000 1110 11ss sSSS:200:?????:?????:13: CAS.L #1,s[!Dreg,Areg,Immd,PC8r,PC16]
-0000 1110 1111 1100:250:?????:?????:10: CAS2.L #2
+0000 1010 11ss sSSS:200:-NZVC:-----:--:13: CAS.B #1,s[!Dreg,Areg,Immd,PC8r,PC16]
+0000 1100 11ss sSSS:200:-NZVC:-----:--:13: CAS.W #1,s[!Dreg,Areg,Immd,PC8r,PC16]
+0000 1100 1111 1100:250:-NZVC:-----:--:10: CAS2.W #2
+0000 1110 zzss sSSS:102:-----:-----:T-:13: MOVES.z #1,s[!Dreg,Areg,Immd,PC8r,PC16]
+0000 1110 11ss sSSS:200:-NZVC:-----:--:13: CAS.L #1,s[!Dreg,Areg,Immd,PC8r,PC16]
+0000 1110 1111 1100:250:-NZVC:-----:--:10: CAS2.L #2
-0000 rrr1 00dd dDDD:050:-----:-----:12: MVPMR.W d[Areg-Ad16],Dr
-0000 rrr1 01dd dDDD:050:-----:-----:12: MVPMR.L d[Areg-Ad16],Dr
-0000 rrr1 10dd dDDD:050:-----:-----:12: MVPRM.W Dr,d[Areg-Ad16]
-0000 rrr1 11dd dDDD:050:-----:-----:12: MVPRM.L Dr,d[Areg-Ad16]
+0000 rrr1 00dd dDDD:050:-----:-----:--:12: MVPMR.W d[Areg-Ad16],Dr
+0000 rrr1 01dd dDDD:050:-----:-----:--:12: MVPMR.L d[Areg-Ad16],Dr
+0000 rrr1 10dd dDDD:050:-----:-----:--:12: MVPRM.W Dr,d[Areg-Ad16]
+0000 rrr1 11dd dDDD:050:-----:-----:--:12: MVPRM.L Dr,d[Areg-Ad16]
-0000 rrr1 00ss sSSS:000:--Z--:-----:11: BTST Dr,s[Dreg]
+0000 rrr1 00ss sSSS:000:--Z--:-----:--:11: BTST Dr,s[Dreg]
- 4 0 4
-0000 rrr1 00ss sSSS:000:--Z--:-----:11: BTST Dr,s[!Areg,Dreg]
+0000 rrr1 00ss sSSS:000:--Z--:-----:--:11: BTST Dr,s[!Areg,Dreg]
- 0 0 4 fea
-0000 rrr1 01ss sSSS:000:--Z--:-----:13: BCHG Dr,s[Dreg]
+0000 rrr1 01ss sSSS:000:--Z--:-----:--:13: BCHG Dr,s[Dreg]
- 6 0 6
-0000 rrr1 01ss sSSS:000:--Z--:-----:13: BCHG Dr,s[!Areg,Dreg,Immd,PC8r,PC16]
+0000 rrr1 01ss sSSS:000:--Z--:-----:--:13: BCHG Dr,s[!Areg,Dreg,Immd,PC8r,PC16]
- 0 0 6 fea
-0000 rrr1 10ss sSSS:000:--Z--:-----:13: BCLR Dr,s[Dreg]
+0000 rrr1 10ss sSSS:000:--Z--:-----:--:13: BCLR Dr,s[Dreg]
- 6 0 6
-0000 rrr1 10ss sSSS:000:--Z--:-----:13: BCLR Dr,s[!Areg,Dreg,Immd,PC8r,PC16]
+0000 rrr1 10ss sSSS:000:--Z--:-----:--:13: BCLR Dr,s[!Areg,Dreg,Immd,PC8r,PC16]
- 0 0 6 fea
-0000 rrr1 11ss sSSS:000:--Z--:-----:13: BSET Dr,s[Dreg]
+0000 rrr1 11ss sSSS:000:--Z--:-----:--:13: BSET Dr,s[Dreg]
- 6 0 6
-0000 rrr1 11ss sSSS:000:--Z--:-----:13: BSET Dr,s[!Areg,Dreg,Immd,PC8r,PC16]
+0000 rrr1 11ss sSSS:000:--Z--:-----:--:13: BSET Dr,s[!Areg,Dreg,Immd,PC8r,PC16]
- 0 0 6 fea
% Move cycles are special cased in gencpu.c
-0001 DDDd ddss sSSS:000:-NZ00:-----:12: MOVE.B s,d[!Areg]
-0011 DDDd ddss sSSS:000:-----:-----:12: MOVEA.W s,d[Areg]
-0011 DDDd ddss sSSS:000:-NZ00:-----:12: MOVE.W s,d[!Areg]
-0010 DDDd ddss sSSS:000:-----:-----:12: MOVEA.L s,d[Areg]
-0010 DDDd ddss sSSS:000:-NZ00:-----:12: MOVE.L s,d[!Areg]
+0001 DDDd ddss sSSS:000:-NZ00:-----:--:12: MOVE.B s,d[!Areg]
+0011 DDDd ddss sSSS:000:-----:-----:--:12: MOVEA.W s,d[Areg]
+0011 DDDd ddss sSSS:000:-NZ00:-----:--:12: MOVE.W s,d[!Areg]
+0010 DDDd ddss sSSS:000:-----:-----:--:12: MOVEA.L s,d[Areg]
+0010 DDDd ddss sSSS:000:-NZ00:-----:--:12: MOVE.L s,d[!Areg]
-0100 0000 zzdd dDDD:000:XxZxC:X-Z--:30: NEGX.z d[Dreg]
+0100 0000 zzdd dDDD:000:XNZVC:X-Z--:--:30: NEGX.z d[Dreg]
- 2 0 2
-0100 0000 zzdd dDDD:000:XxZxC:X-Z--:30: NEGX.z d[!Areg,Dreg]
+0100 0000 zzdd dDDD:000:XNZVC:X-Z--:--:30: NEGX.z d[!Areg,Dreg]
- 0 1 3 fea
-0100 0000 11dd dDDD:001:?????:?????:10: MVSR2.W d[Dreg]
+0100 0000 11dd dDDD:001:-----:XNZVC:T-:10: MVSR2.W d[Dreg]
- 2 0 4
-0100 0000 11dd dDDD:001:?????:?????:10: MVSR2.W d[!Areg,Dreg]
+0100 0000 11dd dDDD:001:-----:XNZVC:T-:10: MVSR2.W d[!Areg,Dreg]
- 2 0 4 cea
-0100 0010 zzdd dDDD:000:-0100:-----:20: CLR.z d[Dreg]
+0100 0010 zzdd dDDD:000:-0100:-----:--:20: CLR.z d[Dreg]
- 2 0 2
-0100 0010 zzdd dDDD:000:-0100:-----:20: CLR.z d[!Areg,Dreg]
+0100 0010 zzdd dDDD:000:-0100:-----:--:20: CLR.z d[!Areg,Dreg]
- 0 1 3 cea
-0100 0010 11dd dDDD:100:?????:?????:10: MVSR2.B d[Dreg]
+0100 0010 11dd dDDD:100:-----:XNZVC:--:10: MVSR2.B d[Dreg]
- 2 0 4
-0100 0010 11dd dDDD:100:?????:?????:10: MVSR2.B d[!Areg,Dreg]
+0100 0010 11dd dDDD:100:-----:XNZVC:--:10: MVSR2.B d[!Areg,Dreg]
- 2 0 4 cea
-0100 0100 zzdd dDDD:000:XNZVC:-----:30: NEG.z d[Dreg]
+0100 0100 zzdd dDDD:000:XNZVC:-----:--:30: NEG.z d[Dreg]
- 2 0 2
-0100 0100 zzdd dDDD:000:XNZVC:-----:30: NEG.z d[!Areg,Dreg]
+0100 0100 zzdd dDDD:000:XNZVC:-----:--:30: NEG.z d[!Areg,Dreg]
- 0 1 3 fea
-0100 0100 11ss sSSS:000:XNZVC:-----:10: MV2SR.B s[Dreg]
+0100 0100 11ss sSSS:000:XNZVC:-----:--:10: MV2SR.B s[Dreg]
- 4 0 4
-0100 0100 11ss sSSS:000:XNZVC:-----:10: MV2SR.B s[!Areg,Dreg]
+0100 0100 11ss sSSS:000:XNZVC:-----:--:10: MV2SR.B s[!Areg,Dreg]
- 0 0 4 fea
-0100 0110 zzdd dDDD:000:-NZ00:-----:30: NOT.z d[Dreg]
+0100 0110 zzdd dDDD:000:-NZ00:-----:--:30: NOT.z d[Dreg]
- 2 0 2
-0100 0110 zzdd dDDD:000:-NZ00:-----:30: NOT.z d[!Areg,Dreg]
+0100 0110 zzdd dDDD:000:-NZ00:-----:--:30: NOT.z d[!Areg,Dreg]
- 0 1 3 fea
-0100 0110 11ss sSSS:002:?????:?????:10: MV2SR.W s[!Areg]
+0100 0110 11ss sSSS:002:XNZVC:XNZVC:T-:10: MV2SR.W s[!Areg]
- 0 0 8 fea
-0100 1000 0000 1rrr:200:-----:-----:31: LINK.L Ar,#2
+0100 1000 0000 1rrr:200:-----:-----:--:31: LINK.L Ar,#2
- 2 0 6
-0100 1000 00dd dDDD:000:X?Z?C:X-Z--:30: NBCD.B d[!Areg]
+0100 1000 00dd dDDD:000:X?Z?C:X-Z--:--:30: NBCD.B d[!Areg]
- 0 0 6
-0100 1000 0100 1kkk:100:?????:?????:10: BKPT #k
+0100 1000 0100 1kkk:100:-----:-----:T-:10: BKPT #k
-0100 1000 01ss sSSS:000:-NZ00:-----:30: SWAP.W s[Dreg]
+0100 1000 01ss sSSS:000:-NZ00:-----:--:30: SWAP.W s[Dreg]
- 4 0 4
-0100 1000 01ss sSSS:000:-----:-----:00: PEA.L s[!Dreg,Areg,Aipi,Apdi,Immd]
+0100 1000 01ss sSSS:000:-----:-----:--:00: PEA.L s[!Dreg,Areg,Aipi,Apdi,Immd]
- 0 2 4 cea
-0100 1000 10dd dDDD:000:-NZ00:-----:30: EXT.W d[Dreg]
+0100 1000 10dd dDDD:000:-NZ00:-----:--:30: EXT.W d[Dreg]
- 4 0 4
-0100 1000 10dd dDDD:000:-----:-----:02: MVMLE.W #1,d[!Dreg,Areg,Aipi]
+0100 1000 10dd dDDD:000:-----:-----:--:02: MVMLE.W #1,d[!Dreg,Areg,Aipi]
-0100 1000 11dd dDDD:000:-NZ00:-----:30: EXT.L d[Dreg]
+0100 1000 11dd dDDD:000:-NZ00:-----:--:30: EXT.L d[Dreg]
- 4 0 4
-0100 1000 11dd dDDD:000:-----:-----:02: MVMLE.L #1,d[!Dreg,Areg,Aipi]
+0100 1000 11dd dDDD:000:-----:-----:--:02: MVMLE.L #1,d[!Dreg,Areg,Aipi]
-0100 1001 11dd dDDD:200:-NZ00:-----:30: EXT.B d[Dreg]
+0100 1001 11dd dDDD:200:-NZ00:-----:--:30: EXT.B d[Dreg]
- 4 0 4
-0100 1010 zzss sSSS:000:-NZ00:-----:10: TST.z s[Dreg]
+0100 1010 zzss sSSS:000:-NZ00:-----:--:10: TST.z s[Dreg]
- 0 0 2
-0100 1010 zzss sSSS:000:-NZ00:-----:10: TST.z s[!Areg,Dreg,PC16,PC8r,Immd]
+0100 1010 zzss sSSS:000:-NZ00:-----:--:10: TST.z s[!Areg,Dreg,PC16,PC8r,Immd]
- 0 0 2 fea
-0100 1010 zzss sSSS:200:-NZ00:-----:10: TST.z s[Areg,PC16,PC8r,Immd]
+0100 1010 zzss sSSS:200:-NZ00:-----:--:10: TST.z s[Areg,PC16,PC8r,Immd]
- 0 0 2 fea
-0100 1010 11dd dDDD:000:?????:?????:30: TAS.B d[Dreg]
+0100 1010 11dd dDDD:000:-NZ00:-----:--:30: TAS.B d[Dreg]
- 0 0 2
-0100 1010 11dd dDDD:000:?????:?????:30: TAS.B d[!Areg,Dreg]
+0100 1010 11dd dDDD:000:-NZ00:-----:--:30: TAS.B d[!Areg,Dreg]
- 0 0 2 fea
-0100 1010 1111 1100:000:?????:?????:00: ILLEGAL
+0100 1010 1111 1100:000:-----:-----:T-:00: ILLEGAL
-0100 1100 00ss sSSS:200:-NZVC:-----:13: MULL.L #1,s[!Areg]
+0100 1100 00ss sSSS:200:-NZVC:-----:--:13: MULL.L #1,s[!Areg]
- 2 0 30 fiea
-0100 1100 01ss sSSS:200:?????:?????:13: DIVL.L #1,s[!Areg]
+0100 1100 01ss sSSS:200:-NZV0:-----:T-:13: DIVL.L #1,s[!Areg]
- 0 0 50 fiea
-0100 1100 10ss sSSS:000:-----:-----:01: MVMEL.W #1,s[!Dreg,Areg,Apdi,Immd]
-0100 1100 11ss sSSS:000:-----:-----:01: MVMEL.L #1,s[!Dreg,Areg,Apdi,Immd]
-0100 1110 0100 JJJJ:000:-----:XNZVC:10: TRAP #J
+0100 1100 10ss sSSS:000:-----:-----:--:01: MVMEL.W #1,s[!Dreg,Areg,Apdi,Immd]
+0100 1100 11ss sSSS:000:-----:-----:--:01: MVMEL.L #1,s[!Dreg,Areg,Apdi,Immd]
+0100 1110 0100 JJJJ:000:-----:XNZVC:--:10: TRAP #J
-0100 1110 0101 0rrr:000:-----:-----:31: LINK.W Ar,#1
+0100 1110 0101 0rrr:000:-----:-----:--:31: LINK.W Ar,#1
- 0 0 4
-0100 1110 0101 1rrr:000:-----:-----:30: UNLK.L Ar
+0100 1110 0101 1rrr:000:-----:-----:--:30: UNLK.L Ar
- 0 0 5
-0100 1110 0110 0rrr:002:-----:-----:10: MVR2USP.L Ar
+0100 1110 0110 0rrr:002:-----:-----:T-:10: MVR2USP.L Ar
- 4 0 4
-0100 1110 0110 1rrr:002:-----:-----:20: MVUSP2R.L Ar
+0100 1110 0110 1rrr:002:-----:-----:T-:20: MVUSP2R.L Ar
- 4 0 4
-0100 1110 0111 0000:002:-----:-----:00: RESET
+0100 1110 0111 0000:002:-----:-----:T-:00: RESET
- 0 0 518
-0100 1110 0111 0001:000:-----:-----:00: NOP
+0100 1110 0111 0001:000:-----:-----:--:00: NOP
- 0 0 2
-0100 1110 0111 0010:002:XNZVC:-----:10: STOP #1
+0100 1110 0111 0010:002:XNZVC:-----:T-:10: STOP #1
- 0 0 8
-0100 1110 0111 0011:002:XNZVC:-----:00: RTE
+0100 1110 0111 0011:002:XNZVC:-----:TR:00: RTE
- 1 9 18
-0100 1110 0111 0100:100:?????:?????:10: RTD #1
+0100 1110 0111 0100:100:-----:-----:-R:10: RTD #1
- 2 0 10
-0100 1110 0111 0101:000:-----:-----:00: RTS
+0100 1110 0111 0101:000:-----:-----:-R:00: RTS
- 1 0 9
-0100 1110 0111 0110:000:-----:XNZVC:00: TRAPV
+0100 1110 0111 0110:000:-----:XNZVC:T-:00: TRAPV
-0100 1110 0111 0111:000:XNZVC:-----:00: RTR
+0100 1110 0111 0111:000:XNZVC:-----:-R:00: RTR
- 1 0 12
-0100 1110 0111 1010:100:?????:?????:10: MOVEC2 #1
+0100 1110 0111 1010:100:-----:-----:T-:10: MOVEC2 #1
- 6 0 6
-0100 1110 0111 1011:100:?????:?????:10: MOVE2C #1
+0100 1110 0111 1011:100:-----:-----:T-:10: MOVE2C #1
- 6 0 6
-0100 1110 10ss sSSS:000://///://///:80: JSR.L s[!Dreg,Areg,Aipi,Apdi,Immd]
+0100 1110 10ss sSSS:000://///://///:-J:80: JSR.L s[!Dreg,Areg,Aipi,Apdi,Immd]
- 0 0 4 jea
-0100 rrr1 00ss sSSS:200:?????:?????:11: CHK.L s[!Areg],Dr
-0100 rrr1 10ss sSSS:000:?????:?????:11: CHK.W s[!Areg],Dr
+0100 rrr1 00ss sSSS:200:-N???:-----:T-:11: CHK.L s[!Areg],Dr
+0100 rrr1 10ss sSSS:000:-N???:-----:T-:11: CHK.W s[!Areg],Dr
-0100 1110 11ss sSSS:000://///://///:80: JMP.L s[!Dreg,Areg,Aipi,Apdi,Immd]
+0100 1110 11ss sSSS:000://///://///:-J:80: JMP.L s[!Dreg,Areg,Aipi,Apdi,Immd]
- 4 0 4 jea
-0100 rrr1 11ss sSSS:000:-----:-----:02: LEA.L s[!Dreg,Areg,Aipi,Apdi,Immd],Ar
+0100 rrr1 11ss sSSS:000:-----:-----:--:02: LEA.L s[!Dreg,Areg,Aipi,Apdi,Immd],Ar
- 2 0 2 cea
-0101 jjj0 01dd dDDD:000:-----:-----:13: ADDA.W #j,d[Areg]
+% This variant of ADDQ is word and long sized only
+0101 jjj0 01dd dDDD:000:-----:-----:--:13: ADDA.W #j,d[Areg]
- 2 0 2
-0101 jjj0 10dd dDDD:000:-----:-----:13: ADDA.L #j,d[Areg]
+0101 jjj0 10dd dDDD:000:-----:-----:--:13: ADDA.L #j,d[Areg]
- 2 0 2
-0101 jjj0 zzdd dDDD:000:XNZVC:-----:13: ADD.z #j,d[Dreg]
+0101 jjj0 zzdd dDDD:000:XNZVC:-----:--:13: ADD.z #j,d[Dreg]
- 2 0 2
-0101 jjj0 zzdd dDDD:000:XNZVC:-----:13: ADD.z #j,d[!Areg,Dreg]
+0101 jjj0 zzdd dDDD:000:XNZVC:-----:--:13: ADD.z #j,d[!Areg,Dreg]
- 0 1 3 fea
-0101 jjj1 01dd dDDD:000:-----:-----:13: SUBA.W #j,d[Areg]
+
+% This variant of SUBQ is word and long sized only
+0101 jjj1 01dd dDDD:000:-----:-----:--:13: SUBA.W #j,d[Areg]
- 2 0 2
-0101 jjj1 10dd dDDD:000:-----:-----:13: SUBA.L #j,d[Areg]
+0101 jjj1 10dd dDDD:000:-----:-----:--:13: SUBA.L #j,d[Areg]
- 2 0 2
-0101 jjj1 zzdd dDDD:000:XNZVC:-----:13: SUB.z #j,d[Dreg]
+0101 jjj1 zzdd dDDD:000:XNZVC:-----:--:13: SUB.z #j,d[Dreg]
- 2 0 2
-0101 jjj1 zzdd dDDD:000:XNZVC:-----:13: SUB.z #j,d[!Areg,Dreg]
+0101 jjj1 zzdd dDDD:000:XNZVC:-----:--:13: SUB.z #j,d[!Areg,Dreg]
- 0 1 3 fea
-0101 cccc 1100 1rrr:000:-----:-++++:31: DBcc.W Dr,#1
+0101 cccc 1100 1rrr:000:-----:-++++:-B:31: DBcc.W Dr,#1
- -1 0 0
-0101 cccc 11dd dDDD:000:-----:-++++:20: Scc.B d[Dreg]
+0101 cccc 11dd dDDD:000:-----:-++++:--:20: Scc.B d[Dreg]
- 0 0 2
-0101 cccc 11dd dDDD:000:-----:-++++:20: Scc.B d[!Areg,Dreg]
+0101 cccc 11dd dDDD:000:-----:-++++:--:20: Scc.B d[!Areg,Dreg]
- 0 0 2 cea
-0101 cccc 1111 1010:200:?????:?????:10: TRAPcc #1
-0101 cccc 1111 1011:200:?????:?????:10: TRAPcc #2
-0101 cccc 1111 1100:200:?????:?????:00: TRAPcc
+0101 cccc 1111 1010:200:-----:-????:T-:10: TRAPcc #1
+0101 cccc 1111 1011:200:-----:-????:T-:10: TRAPcc #2
+0101 cccc 1111 1100:200:-----:-????:T-:00: TRAPcc
% Bxx.L is 68020 only, but setting the CPU level to 2 would give illegal
% instruction exceptions when compiling a 68000 only emulation, which isn't
% what we want either.
-0110 0001 0000 0000:000://///://///:40: BSR.W #1
+0110 0001 0000 0000:000://///://///:-B:40: BSR.W #1
- 2 0 6
-0110 0001 IIII IIII:000://///://///:40: BSR.B #i
+0110 0001 IIII IIII:000://///://///:-B:40: BSR.B #i
- 2 0 6
-0110 0001 1111 1111:000://///://///:40: BSR.L #2
+0110 0001 1111 1111:000://///://///:-B:40: BSR.L #2
- 2 0 6
-0110 CCCC 0000 0000:000:-----:-++++:40: Bcc.W #1
+0110 CCCC 0000 0000:000:-----:-++++:-B:40: Bcc.W #1
- -1 0 0
-0110 CCCC IIII IIII:000:-----:-++++:40: Bcc.B #i
+0110 CCCC IIII IIII:000:-----:-++++:-B:40: Bcc.B #i
- -1 0 0
-0110 CCCC 1111 1111:000:-----:-++++:40: Bcc.L #2
+0110 CCCC 1111 1111:000:-----:-++++:-B:40: Bcc.L #2
- -1 0 0
-0111 rrr0 iiii iiii:000:-NZ00:-----:12: MOVE.L #i,Dr
+0111 rrr0 iiii iiii:000:-NZ00:-----:--:12: MOVE.L #i,Dr
-1000 rrr0 zzss sSSS:000:-NZ00:-----:13: OR.z s[Dreg],Dr
+1000 rrr0 zzss sSSS:000:-NZ00:-----:--:13: OR.z s[Dreg],Dr
- 2 0 2
-1000 rrr0 zzss sSSS:000:-NZ00:-----:13: OR.z s[!Areg,Dreg],Dr
+1000 rrr0 zzss sSSS:000:-NZ00:-----:--:13: OR.z s[!Areg,Dreg],Dr
- 0 0 2 fea
-1000 rrr0 11ss sSSS:000:?????:?????:13: DIVU.W s[Dreg],Dr
+1000 rrr0 11ss sSSS:000:-NZV0:-----:T-:13: DIVU.W s[Dreg],Dr
- 2 0 20
-1000 rrr0 11ss sSSS:000:?????:?????:13: DIVU.W s[!Areg,Dreg],Dr
+1000 rrr0 11ss sSSS:000:-NZV0:-----:T-:13: DIVU.W s[!Areg,Dreg],Dr
- 0 0 20 fea
-1000 rrr1 00dd dDDD:000:XxZxC:X-Z--:13: SBCD.B d[Dreg],Dr
+1000 rrr1 00dd dDDD:000:X?Z?C:X-Z--:--:13: SBCD.B d[Dreg],Dr
- 0 0 4
-1000 rrr1 00dd dDDD:000:XxZxC:X-Z--:13: SBCD.B d[Areg-Apdi],Arp
+1000 rrr1 00dd dDDD:000:X?Z?C:X-Z--:--:13: SBCD.B d[Areg-Apdi],Arp
- 2 1 13
-1000 rrr1 zzdd dDDD:000:-NZ00:-----:13: OR.z Dr,d[!Areg,Dreg]
+1000 rrr1 zzdd dDDD:000:-NZ00:-----:--:13: OR.z Dr,d[!Areg,Dreg]
- 0 1 3 fea
-1000 rrr1 01dd dDDD:200:?????:?????:12: PACK d[Dreg],Dr
+1000 rrr1 01dd dDDD:200:-----:-----:--:12: PACK d[Dreg],Dr
- 6 0 6
-1000 rrr1 01dd dDDD:200:?????:?????:12: PACK d[Areg-Apdi],Arp
+1000 rrr1 01dd dDDD:200:-----:-----:--:12: PACK d[Areg-Apdi],Arp
- 2 1 11
-1000 rrr1 10dd dDDD:200:?????:?????:12: UNPK d[Dreg],Dr
+1000 rrr1 10dd dDDD:200:-----:-----:--:12: UNPK d[Dreg],Dr
- 8 0 8
-1000 rrr1 10dd dDDD:200:?????:?????:12: UNPK d[Areg-Apdi],Arp
+1000 rrr1 10dd dDDD:200:-----:-----:--:12: UNPK d[Areg-Apdi],Arp
- 2 1 11
-1000 rrr1 11ss sSSS:000:?????:?????:13: DIVS.W s[Dreg],Dr
+1000 rrr1 11ss sSSS:000:-NZV0:-----:T-:13: DIVS.W s[Dreg],Dr
- 2 0 20
-1000 rrr1 11ss sSSS:000:?????:?????:13: DIVS.W s[!Areg,Dreg],Dr
+1000 rrr1 11ss sSSS:000:-NZV0:-----:T-:13: DIVS.W s[!Areg,Dreg],Dr
- 0 0 20 fea
-1001 rrr0 zzss sSSS:000:XNZVC:-----:13: SUB.z s[Areg,Dreg],Dr
+1001 rrr0 zzss sSSS:000:XNZVC:-----:--:13: SUB.z s[Areg,Dreg],Dr
- 2 0 2
-1001 rrr0 zzss sSSS:000:XNZVC:-----:13: SUB.z s[!Areg,Dreg],Dr
+1001 rrr0 zzss sSSS:000:XNZVC:-----:--:13: SUB.z s[!Areg,Dreg],Dr
- 0 0 2 fea
-1001 rrr0 11ss sSSS:000:-----:-----:13: SUBA.W s[Areg,Dreg],Ar
+1001 rrr0 11ss sSSS:000:-----:-----:--:13: SUBA.W s[Areg,Dreg],Ar
- 4 0 4
-1001 rrr0 11ss sSSS:000:-----:-----:13: SUBA.W s[!Areg,Dreg],Ar
+1001 rrr0 11ss sSSS:000:-----:-----:--:13: SUBA.W s[!Areg,Dreg],Ar
- 0 0 4 fea
-1001 rrr1 zzdd dDDD:000:XNZVC:X-Z--:13: SUBX.z d[Dreg],Dr
+1001 rrr1 zzdd dDDD:000:XNZVC:X-Z--:--:13: SUBX.z d[Dreg],Dr
- 2 0 2
-1001 rrr1 zzdd dDDD:000:XNZVC:X-Z--:13: SUBX.z d[Areg-Apdi],Arp
+1001 rrr1 zzdd dDDD:000:XNZVC:X-Z--:--:13: SUBX.z d[Areg-Apdi],Arp
- 2 1 9
-1001 rrr1 zzdd dDDD:000:XNZVC:-----:13: SUB.z Dr,d[!Areg,Dreg]
+1001 rrr1 zzdd dDDD:000:XNZVC:-----:--:13: SUB.z Dr,d[!Areg,Dreg]
- 0 1 3 fea
-1001 rrr1 11ss sSSS:000:-----:-----:13: SUBA.L s[Areg,Dreg],Ar
+1001 rrr1 11ss sSSS:000:-----:-----:--:13: SUBA.L s[Areg,Dreg],Ar
- 2 0 2
-1001 rrr1 11ss sSSS:000:-----:-----:13: SUBA.L s[!Areg,Dreg],Ar
+1001 rrr1 11ss sSSS:000:-----:-----:--:13: SUBA.L s[!Areg,Dreg],Ar
- 0 0 2 fea
-1011 rrr0 zzss sSSS:000:-NZVC:-----:11: CMP.z s[Areg,Dreg],Dr
+1011 rrr0 zzss sSSS:000:-NZVC:-----:--:11: CMP.z s[Areg,Dreg],Dr
- 2 0 2
-1011 rrr0 zzss sSSS:000:-NZVC:-----:11: CMP.z s[!Areg,Dreg],Dr
+1011 rrr0 zzss sSSS:000:-NZVC:-----:--:11: CMP.z s[!Areg,Dreg],Dr
- 0 0 2 fea
-1011 rrr0 11ss sSSS:000:-NZVC:-----:11: CMPA.W s[Areg,Dreg],Ar
+1011 rrr0 11ss sSSS:000:-NZVC:-----:--:11: CMPA.W s[Areg,Dreg],Ar
- 4 0 4
-1011 rrr0 11ss sSSS:000:-NZVC:-----:11: CMPA.W s[!Areg,Dreg],Ar
+1011 rrr0 11ss sSSS:000:-NZVC:-----:--:11: CMPA.W s[!Areg,Dreg],Ar
- 0 0 4 fea
-1011 rrr1 11ss sSSS:000:-NZVC:-----:11: CMPA.L s[Areg,Dreg],Ar
+1011 rrr1 11ss sSSS:000:-NZVC:-----:--:11: CMPA.L s[Areg,Dreg],Ar
- 4 0 4
-1011 rrr1 11ss sSSS:000:-NZVC:-----:11: CMPA.L s[!Areg,Dreg],Ar
+1011 rrr1 11ss sSSS:000:-NZVC:-----:--:11: CMPA.L s[!Areg,Dreg],Ar
- 0 0 4 fea
-1011 rrr1 zzdd dDDD:000:-NZVC:-----:11: CMPM.z d[Areg-Aipi],ArP
+1011 rrr1 zzdd dDDD:000:-NZVC:-----:--:11: CMPM.z d[Areg-Aipi],ArP
- 0 0 8
-1011 rrr1 zzdd dDDD:000:-NZ00:-----:13: EOR.z Dr,d[Dreg]
+1011 rrr1 zzdd dDDD:000:-NZ00:-----:--:13: EOR.z Dr,d[Dreg]
- 2 0 2
-1011 rrr1 zzdd dDDD:000:-NZ00:-----:13: EOR.z Dr,d[!Areg,Dreg]
+1011 rrr1 zzdd dDDD:000:-NZ00:-----:--:13: EOR.z Dr,d[!Areg,Dreg]
- 0 1 3 fea
-1100 rrr0 zzss sSSS:000:-NZ00:-----:13: AND.z s[Dreg],Dr
+1100 rrr0 zzss sSSS:000:-NZ00:-----:--:13: AND.z s[Dreg],Dr
- 2 0 2 fea
-1100 rrr0 zzss sSSS:000:-NZ00:-----:13: AND.z s[!Areg,Dreg],Dr
+1100 rrr0 zzss sSSS:000:-NZ00:-----:--:13: AND.z s[!Areg,Dreg],Dr
- 0 1 3 fea
-1100 rrr0 11ss sSSS:000:-NZ00:-----:13: MULU.W s[!Areg],Dr
+1100 rrr0 11ss sSSS:000:-NZ00:-----:--:13: MULU.W s[!Areg],Dr
- 2 0 12 fea
-1100 rrr1 00dd dDDD:000:XxZxC:X-Z--:13: ABCD.B d[Dreg],Dr
+1100 rrr1 00dd dDDD:000:X?Z?C:X-Z--:--:13: ABCD.B d[Dreg],Dr
- 0 0 4
-1100 rrr1 00dd dDDD:000:XxZxC:X-Z--:13: ABCD.B d[Areg-Apdi],Arp
+1100 rrr1 00dd dDDD:000:X?Z?C:X-Z--:--:13: ABCD.B d[Areg-Apdi],Arp
- 2 1 13
-1100 rrr1 zzdd dDDD:000:-NZ00:-----:13: AND.z Dr,d[!Areg,Dreg]
+1100 rrr1 zzdd dDDD:000:-NZ00:-----:--:13: AND.z Dr,d[!Areg,Dreg]
- 0 1 3 fea
-1100 rrr1 01dd dDDD:000:-----:-----:33: EXG.L Dr,d[Dreg]
+1100 rrr1 01dd dDDD:000:-----:-----:--:33: EXG.L Dr,d[Dreg]
- 4 0 4
-1100 rrr1 01dd dDDD:000:-----:-----:33: EXG.L Ar,d[Areg]
+1100 rrr1 01dd dDDD:000:-----:-----:--:33: EXG.L Ar,d[Areg]
- 4 0 4
-1100 rrr1 10dd dDDD:000:-----:-----:33: EXG.L Dr,d[Areg]
+1100 rrr1 10dd dDDD:000:-----:-----:--:33: EXG.L Dr,d[Areg]
- 4 0 4
-1100 rrr1 11ss sSSS:000:-NZ00:-----:13: MULS.W s[!Areg],Dr
+1100 rrr1 11ss sSSS:000:-NZ00:-----:--:13: MULS.W s[!Areg],Dr
- 2 0 12 fea
-1101 rrr0 zzss sSSS:000:XNZVC:-----:13: ADD.z s[Areg,Dreg],Dr
+1101 rrr0 zzss sSSS:000:XNZVC:-----:--:13: ADD.z s[Areg,Dreg],Dr
- 2 0 2
-1101 rrr0 zzss sSSS:000:XNZVC:-----:13: ADD.z s[!Areg,Dreg],Dr
+1101 rrr0 zzss sSSS:000:XNZVC:-----:--:13: ADD.z s[!Areg,Dreg],Dr
- 0 0 2 fea
-1101 rrr0 11ss sSSS:000:-----:-----:13: ADDA.W s[Areg,Dreg],Ar
+1101 rrr0 11ss sSSS:000:-----:-----:--:13: ADDA.W s[Areg,Dreg],Ar
- 0 0 4
-1101 rrr0 11ss sSSS:000:-----:-----:13: ADDA.W s[!Areg,Dreg],Ar
+1101 rrr0 11ss sSSS:000:-----:-----:--:13: ADDA.W s[!Areg,Dreg],Ar
- 4 0 4 fea
-1101 rrr1 zzdd dDDD:000:XNZVC:X-Z--:13: ADDX.z d[Dreg],Dr
+1101 rrr1 zzdd dDDD:000:XNZVC:X-Z--:--:13: ADDX.z d[Dreg],Dr
- 2 0 2
-1101 rrr1 zzdd dDDD:000:XNZVC:X-Z--:13: ADDX.z d[Areg-Apdi],Arp
+1101 rrr1 zzdd dDDD:000:XNZVC:X-Z--:--:13: ADDX.z d[Areg-Apdi],Arp
- 2 1 9
-1101 rrr1 zzdd dDDD:000:XNZVC:-----:13: ADD.z Dr,d[!Areg,Dreg]
+1101 rrr1 zzdd dDDD:000:XNZVC:-----:--:13: ADD.z Dr,d[!Areg,Dreg]
- 0 1 3 fea
-1101 rrr1 11ss sSSS:000:-----:-----:13: ADDA.L s[Areg,Dreg],Ar
+1101 rrr1 11ss sSSS:000:-----:-----:--:13: ADDA.L s[Areg,Dreg],Ar
- 2 0 2
-1101 rrr1 11ss sSSS:000:-----:-----:13: ADDA.L s[!Areg,Dreg],Ar
+1101 rrr1 11ss sSSS:000:-----:-----:--:13: ADDA.L s[!Areg,Dreg],Ar
- 0 0 2 fea
-1110 jjjf zz00 0RRR:000:XNZVC:-----:13: ASf.z #j,DR
+1110 jjjf zz00 0RRR:000:XNZVC:-----:--:13: ASf.z #j,DR
- 2 0 6
-1110 jjjf zz00 1RRR:000:XNZ0C:-----:13: LSf.z #j,DR
+1110 jjjf zz00 1RRR:000:XNZ0C:-----:--:13: LSf.z #j,DR
- 4 0 4
-1110 jjjf zz01 0RRR:000:XNZ0C:X----:13: ROXf.z #j,DR
+1110 jjjf zz01 0RRR:000:XNZ0C:X----:--:13: ROXf.z #j,DR
- 10 0 12
-1110 jjjf zz01 1RRR:000:-NZ0C:-----:13: ROf.z #j,DR
+1110 jjjf zz01 1RRR:000:-NZ0C:-----:--:13: ROf.z #j,DR
- 4 0 6
-1110 rrrf zz10 0RRR:000:XNZVC:X----:13: ASf.z Dr,DR
+1110 rrrf zz10 0RRR:000:XNZVC:X----:--:13: ASf.z Dr,DR
- 4 0 6
-1110 rrrf zz10 1RRR:000:XNZ0C:X----:13: LSf.z Dr,DR
+1110 rrrf zz10 1RRR:000:XNZ0C:X----:--:13: LSf.z Dr,DR
- 6 0 6
-1110 rrrf zz11 0RRR:000:XNZ0C:X----:13: ROXf.z Dr,DR
+1110 rrrf zz11 0RRR:000:XNZ0C:X----:--:13: ROXf.z Dr,DR
- 10 0 12
-1110 rrrf zz11 1RRR:000:-NZ0C:-----:13: ROf.z Dr,DR
+1110 rrrf zz11 1RRR:000:-NZ0C:-----:--:13: ROf.z Dr,DR
- 6 0 8
-1110 000f 11dd dDDD:000:XNZVC:-----:13: ASfW.W d[!Dreg,Areg]
+1110 000f 11dd dDDD:000:XNZVC:-----:--:13: ASfW.W d[!Dreg,Areg]
- 0 0 4 fea
-1110 001f 11dd dDDD:000:XNZ0C:-----:13: LSfW.W d[!Dreg,Areg]
+1110 001f 11dd dDDD:000:XNZ0C:-----:--:13: LSfW.W d[!Dreg,Areg]
- 0 0 4 fea
-1110 010f 11dd dDDD:000:XNZ0C:X----:13: ROXfW.W d[!Dreg,Areg]
+1110 010f 11dd dDDD:000:XNZ0C:X----:--:13: ROXfW.W d[!Dreg,Areg]
- 0 0 4 fea
-1110 011f 11dd dDDD:000:-NZ0C:-----:13: ROfW.W d[!Dreg,Areg]
+1110 011f 11dd dDDD:000:-NZ0C:-----:--:13: ROfW.W d[!Dreg,Areg]
- 0 0 6 fea
-1110 1000 11ss sSSS:200:?????:?????:11: BFTST #1,s[!Areg,Apdi,Aipi,Immd]
-1110 1001 11ss sSSS:200:?????:?????:11: BFEXTU #1,s[!Areg,Apdi,Aipi,Immd]
-1110 1010 11ss sSSS:200:?????:?????:13: BFCHG #1,s[!Areg,Apdi,Aipi,Immd,PC8r,PC16]
-1110 1011 11ss sSSS:200:?????:?????:11: BFEXTS #1,s[!Areg,Apdi,Aipi,Immd]
-1110 1100 11ss sSSS:200:?????:?????:13: BFCLR #1,s[!Areg,Apdi,Aipi,Immd,PC8r,PC16]
-1110 1101 11ss sSSS:200:?????:?????:11: BFFFO #1,s[!Areg,Apdi,Aipi,Immd]
-1110 1110 11ss sSSS:200:?????:?????:13: BFSET #1,s[!Areg,Apdi,Aipi,Immd,PC8r,PC16]
-1110 1111 11ss sSSS:200:?????:?????:13: BFINS #1,s[!Areg,Apdi,Aipi,Immd,PC8r,PC16]
+1110 1000 11ss sSSS:200:-NZ00:-----:--:11: BFTST #1,s[!Areg,Apdi,Aipi,Immd]
+1110 1001 11ss sSSS:200:-NZ00:-----:--:11: BFEXTU #1,s[!Areg,Apdi,Aipi,Immd]
+1110 1010 11ss sSSS:200:-NZ00:-----:--:13: BFCHG #1,s[!Areg,Apdi,Aipi,Immd,PC8r,PC16]
+1110 1011 11ss sSSS:200:-NZ00:-----:--:11: BFEXTS #1,s[!Areg,Apdi,Aipi,Immd]
+1110 1100 11ss sSSS:200:-NZ00:-----:--:13: BFCLR #1,s[!Areg,Apdi,Aipi,Immd,PC8r,PC16]
+1110 1101 11ss sSSS:200:-NZ00:-----:--:11: BFFFO #1,s[!Areg,Apdi,Aipi,Immd]
+1110 1110 11ss sSSS:200:-NZ00:-----:--:13: BFSET #1,s[!Areg,Apdi,Aipi,Immd,PC8r,PC16]
+1110 1111 11ss sSSS:200:-NZ00:-----:--:13: BFINS #1,s[!Areg,Apdi,Aipi,Immd,PC8r,PC16]
% floating point co processor
-1111 0010 00ss sSSS:200:?????:?????:11: FPP #1,s
-1111 0010 01ss sSSS:200:?????:?????:11: FDBcc #1,s[Areg-Dreg]
-1111 0010 01ss sSSS:200:?????:?????:11: FScc #1,s[!Areg,Immd,PC8r,PC16]
-1111 0010 0111 1010:200:?????:?????:10: FTRAPcc #1
-1111 0010 0111 1011:200:?????:?????:10: FTRAPcc #2
-1111 0010 0111 1100:200:?????:?????:00: FTRAPcc
-1111 0010 10KK KKKK:200:?????:?????:11: FBcc #K,#1
-1111 0010 11KK KKKK:200:?????:?????:11: FBcc #K,#2
-1111 0011 00ss sSSS:202:?????:?????:20: FSAVE s[!Dreg,Areg,Aipi,Immd,PC8r,PC16]
-1111 0011 01ss sSSS:202:?????:?????:10: FRESTORE s[!Dreg,Areg,Apdi,Immd]
+1111 0010 00ss sSSS:200:-----:-----:--:11: FPP #1,s
+1111 0010 01ss sSSS:200:-----:-----:-B:11: FDBcc #1,s[Areg-Dreg]
+1111 0010 01ss sSSS:200:-----:-----:--:11: FScc #1,s[!Areg,Immd,PC8r,PC16]
+1111 0010 0111 1010:200:-----:-----:T-:10: FTRAPcc #1
+1111 0010 0111 1011:200:-----:-----:T-:10: FTRAPcc #2
+1111 0010 0111 1100:200:-----:-----:T-:00: FTRAPcc
+1111 0010 10KK KKKK:200:-----:-----:-B:11: FBcc #K,#1
+1111 0010 11KK KKKK:200:-----:-----:-B:11: FBcc #K,#2
+1111 0011 00ss sSSS:202:-----:-----:--:20: FSAVE s[!Dreg,Areg,Aipi,Immd,PC8r,PC16]
+1111 0011 01ss sSSS:202:-----:-----:--:10: FRESTORE s[!Dreg,Areg,Apdi,Immd]
% 68030 MMU (allowed addressing modes not checked!)
-1111 0000 00ss sSSS:342:?????:?????:11: MMUOP030 s[Dreg,Areg,Apdi,Aipi,Aind,Ad16,Ad8r,absl,absw],#1
+1111 0000 00ss sSSS:342:-----:-----:T-:11: MMUOP030 s[Dreg,Areg,Apdi,Aipi,Aind,Ad16,Ad8r,absl,absw],#1
% 68040/68060 instructions
-1111 0100 pp00 1rrr:402:-----:-----:02: CINVL #p,Ar
-1111 0100 pp01 0rrr:402:-----:-----:02: CINVP #p,Ar
-1111 0100 pp01 1rrr:402:-----:-----:00: CINVA #p
-1111 0100 pp10 1rrr:402:-----:-----:02: CPUSHL #p,Ar
-1111 0100 pp11 0rrr:402:-----:-----:02: CPUSHP #p,Ar
-1111 0100 pp11 1rrr:402:-----:-----:00: CPUSHA #p
-1111 0101 0000 0rrr:402:-----:-----:00: PFLUSHN Ara
-1111 0101 0000 1rrr:402:-----:-----:00: PFLUSH Ara
-1111 0101 0001 0rrr:402:-----:-----:00: PFLUSHAN Ara
-1111 0101 0001 1rrr:402:-----:-----:00: PFLUSHA Ara
+1111 0100 pp00 1rrr:402:-----:-----:T-:02: CINVL #p,Ar
+1111 0100 pp01 0rrr:402:-----:-----:T-:02: CINVP #p,Ar
+1111 0100 pp01 1rrr:402:-----:-----:T-:00: CINVA #p
+1111 0100 pp10 1rrr:402:-----:-----:T-:02: CPUSHL #p,Ar
+1111 0100 pp11 0rrr:402:-----:-----:T-:02: CPUSHP #p,Ar
+1111 0100 pp11 1rrr:402:-----:-----:T-:00: CPUSHA #p
+1111 0101 0000 0rrr:402:-----:-----:T-:00: PFLUSHN Ara
+1111 0101 0000 1rrr:402:-----:-----:T-:00: PFLUSH Ara
+1111 0101 0001 0rrr:402:-----:-----:T-:00: PFLUSHAN Ara
+1111 0101 0001 1rrr:402:-----:-----:T-:00: PFLUSHA Ara
% 68040 only
-1111 0101 0100 1rrr:452:-----:-----:00: PTESTW Ara
-1111 0101 0110 1rrr:452:-----:-----:00: PTESTR Ara
+1111 0101 0100 1rrr:452:-----:-----:T-:00: PTESTW Ara
+1111 0101 0110 1rrr:452:-----:-----:T-:00: PTESTR Ara
% destination register number is encoded in the following word
-1111 0110 0010 0rrr:400:-----:-----:12: MOVE16 ArP,AxP
-1111 0110 00ss sSSS:400:-----:-----:12: MOVE16 s[Dreg-Aipi],L
-1111 0110 00dd dDDD:400:-----:-----:12: MOVE16 L,d[Areg-Aipi]
-1111 0110 00ss sSSS:400:-----:-----:12: MOVE16 s[Aind],L
-1111 0110 00dd dDDD:400:-----:-----:12: MOVE16 L,d[Aipi-Aind]
+1111 0110 0010 0rrr:400:-----:-----:--:12: MOVE16 ArP,AxP
+1111 0110 00ss sSSS:400:-----:-----:--:12: MOVE16 s[Dreg-Aipi],Al
+1111 0110 00dd dDDD:400:-----:-----:--:12: MOVE16 Al,d[Areg-Aipi]
+1111 0110 00ss sSSS:400:-----:-----:--:12: MOVE16 s[Aind],Al
+1111 0110 00dd dDDD:400:-----:-----:--:12: MOVE16 Al,d[Aipi-Aind]
% 68060
-1111 1000 0000 0000:500:?????:?????:10: LPSTOP #1
-1111 0101 1000 1rrr:502:-----:-----:00: PLPAW Ara
-1111 0101 1100 1rrr:502:-----:-----:00: PLPAR Ara
+1111 1000 0000 0000:500:XNZVC:-----:T-:10: LPSTOP #1
+1111 0101 1000 1rrr:502:-----:-----:T-:00: PLPAW Ara
+1111 0101 1100 1rrr:502:-----:-----:T-:00: PLPAR Ara
% "Debug Pipe Control Mode Commands"
-0100 1010 1100 1000:502:?????:?????:00: HALT
-0100 1010 1100 1100:500:?????:?????:00: PULSE
+0100 1010 1100 1000:502:-----:-----:--:00: HALT
+0100 1010 1100 1100:500:-----:-----:--:00: PULSE