From f4b4a3f6146fe288fa862961a691765dd04043af Mon Sep 17 00:00:00 2001 From: Toni Wilen Date: Sun, 11 Aug 2019 22:02:21 +0300 Subject: [PATCH] CPU tester updates and undocumented flag fixes (68020 ABCD, NBCD, SBCD, CHK, CHK2) and more. Replaced tester disassembler with version that supports 68020+ and FPU instructions. --- cputest.cpp | 497 ++++++++---- cputest/adis/decode_ea.c | 402 ++++++++++ cputest/adis/defs.h | 522 ++++++++++++ cputest/adis/globals.c | 327 ++++++++ cputest/adis/opcode_handler_cpu.c | 1220 +++++++++++++++++++++++++++++ cputest/adis/opcode_handler_fpu.c | 402 ++++++++++ cputest/adis/opcode_handler_mmu.c | 228 ++++++ cputest/adis/opcodes_cpu.c | 1123 ++++++++++++++++++++++++++ cputest/adis/opcodes_fpu.c | 211 +++++ cputest/adis/opcodes_mmu.c | 63 ++ cputest/adis/string_recog.h | 309 ++++++++ cputest/adis/util.c | 999 +++++++++++++++++++++++ cputest/asm.S | 1 + cputest/cputestgen.ini | 26 +- cputest/main.c | 186 +++-- cputest/makefile | 34 +- cputest_support.cpp | 14 +- disasm.cpp | 13 + fpp.cpp | 32 +- gencpu.cpp | 73 +- include/fpp.h | 7 + include/newcpu.h | 3 +- newcpu.cpp | 59 +- newcpu_common.cpp | 137 +++- readcpu.cpp | 1 - 25 files changed, 6545 insertions(+), 344 deletions(-) create mode 100644 cputest/adis/decode_ea.c create mode 100644 cputest/adis/defs.h create mode 100644 cputest/adis/globals.c create mode 100644 cputest/adis/opcode_handler_cpu.c create mode 100644 cputest/adis/opcode_handler_fpu.c create mode 100644 cputest/adis/opcode_handler_mmu.c create mode 100644 cputest/adis/opcodes_cpu.c create mode 100644 cputest/adis/opcodes_fpu.c create mode 100644 cputest/adis/opcodes_mmu.c create mode 100644 cputest/adis/string_recog.h create mode 100644 cputest/adis/util.c diff --git a/cputest.cpp b/cputest.cpp index 003a6583..a90002f5 100644 --- a/cputest.cpp +++ b/cputest.cpp @@ -4,6 +4,7 @@ #include "readcpu.h" #include "disasm.h" #include "ini.h" +#include "fpp.h" #include "options.h" @@ -30,7 +31,6 @@ static uae_u32 registers[] = 0x00000000 // replaced with stack }; -// TODO: fill FPU registers static floatx80 fpuregisters[8]; static uae_u32 fpu_fpiar, fpu_fpcr, fpu_fpsr; @@ -62,7 +62,6 @@ static int feature_full_extension_format = 0; static uae_u32 feature_addressing_modes[2]; static int ad8r[2], pc8r[2]; -#define LOW_MEMORY_END 0x8000 #define HIGH_MEMORY_START (0x01000000 - 0x8000) // large enough for RTD @@ -75,9 +74,11 @@ static uae_u32 test_low_memory_start; static uae_u32 test_low_memory_end; static uae_u32 test_high_memory_start; static uae_u32 test_high_memory_end; +static uae_u32 low_memory_size = 32768; +static uae_u32 high_memory_size = 32768; -static uae_u8 low_memory[32768], high_memory[32768], *test_memory; -static uae_u8 low_memory_temp[32768], high_memory_temp[32768], *test_memory_temp; +static uae_u8 *low_memory, *high_memory, *test_memory; +static uae_u8 *low_memory_temp, *high_memory_temp, *test_memory_temp; static uae_u8 dummy_memory[4]; static uaecptr test_memory_start, test_memory_end, opcode_memory_start; static uae_u32 test_memory_size; @@ -131,7 +132,7 @@ static bool valid_address(uaecptr addr, int size, int w) { addr &= addressing_mask; size--; - if (addr + size < LOW_MEMORY_END) { + if (addr + size < low_memory_size) { if (addr < test_low_memory_start || test_low_memory_start == 0xffffffff) goto oob; // exception vectors needed during tests @@ -181,7 +182,7 @@ static uae_u8 *get_addr(uaecptr addr, int size, int w) } addr &= addressing_mask; size--; - if (addr + size < LOW_MEMORY_END) { + if (addr + size < low_memory_size) { return low_memory + addr; } else if (addr >= HIGH_MEMORY_START && addr < HIGH_MEMORY_START + 0x8000) { return high_memory + (addr - HIGH_MEMORY_START); @@ -202,29 +203,6 @@ oob: return dummy_memory; } -uae_u32 REGPARAM2 op_illg_1(uae_u32 opcode) -{ - if ((opcode & 0xf000) == 0xf000) - test_exception = 11; - else if ((opcode & 0xf000) == 0xa000) - test_exception = 10; - else - test_exception = 4; - return 0; -} -uae_u32 REGPARAM2 op_unimpl_1(uae_u32 opcode) -{ - return 0; -} -void REGPARAM2 op_unimpl(uae_u32 opcode) -{ - op_unimpl_1(opcode); -} -uae_u32 REGPARAM2 op_illg(uae_u32 opcode) -{ - return op_illg_1(opcode); -} - uae_u16 get_word_test_prefetch(int o) { // no real prefetch @@ -429,6 +407,19 @@ uae_u32 sfc_nommu_get_long(uaecptr addr) return get_long_test(addr); } +void dfc_nommu_put_byte(uaecptr addr, uae_u32 v) +{ + put_byte_test(addr, v); +} +void dfc_nommu_put_word(uaecptr addr, uae_u32 v) +{ + put_word_test(addr, v); +} +void dfc_nommu_put_long(uaecptr addr, uae_u32 v) +{ + put_long_test(addr, v); +} + uae_u32 memory_get_byte(uaecptr addr) { return get_byte_test(addr); @@ -686,8 +677,26 @@ static void doexcstack(void) mode |= test_exception_3_w ? 0 : 16; Exception_build_68000_address_error_stack_frame(mode, opcode, test_exception_addr, regs.pc); } - } else if (cpu_lvl > 0) { - Exception_build_stack_frame_common(regs.instruction_pc, regs.pc, 0, test_exception); + } else if (cpu_lvl == 1) { + if (test_exception == 3) { + uae_u16 ssw = (sv ? 4 : 0) | (test_exception_3_inst ? 2 : 1); + ssw |= test_exception_3_w ? 0 : 0x100; + ssw |= test_exception_3_inst ? 0 : 0x2000; + regs.mmu_fault_addr = test_exception_addr; + Exception_build_stack_frame(regs.instruction_pc, regs.pc, ssw, 3, 0x08); + } else { + Exception_build_stack_frame_common(regs.instruction_pc, regs.pc, 0, test_exception); + } + } else if (cpu_lvl == 2) { + if (test_exception == 3) { + uae_u16 ssw = (sv ? 4 : 0) | (test_exception_3_inst ? 2 : 1); + ssw |= test_exception_3_w ? 0 : 0x40; + ssw |= 0x20; + regs.mmu_fault_addr = test_exception_addr; + Exception_build_stack_frame(regs.instruction_pc, regs.pc, ssw, 3, 0x0a); + } else { + Exception_build_stack_frame_common(regs.instruction_pc, regs.pc, 0, test_exception); + } } exception_stack_frame_size = test_memory_end + EXTRA_RESERVED_SPACE - m68k_areg(regs, 7); @@ -696,6 +705,35 @@ static void doexcstack(void) noaccesshistory = noac; } +uae_u32 REGPARAM2 op_illg_1(uae_u32 opcode) +{ + if ((opcode & 0xf000) == 0xf000) + test_exception = 11; + else if ((opcode & 0xf000) == 0xa000) + test_exception = 10; + else + test_exception = 4; + doexcstack(); + return 0; +} +void REGPARAM2 op_unimpl(uae_u32 opcode) +{ + test_exception = 61; + doexcstack(); +} +uae_u32 REGPARAM2 op_unimpl_1(uae_u32 opcode) +{ + if ((opcode & 0xf000) == 0xf000 || currprefs.cpu_model < 68060) + op_illg(opcode); + else + op_unimpl(opcode); + return 0; +} +uae_u32 REGPARAM2 op_illg(uae_u32 opcode) +{ + return op_illg_1(opcode); +} + void exception3_read(uae_u32 opcode, uae_u32 addr) { test_exception = 3; @@ -869,8 +907,8 @@ static void fill_memory_buffer(uae_u8 *p, int size) static void fill_memory(void) { - fill_memory_buffer(low_memory_temp, 32768); - fill_memory_buffer(high_memory_temp, 32768); + fill_memory_buffer(low_memory_temp, low_memory_size); + fill_memory_buffer(high_memory_temp, high_memory_size); fill_memory_buffer(test_memory_temp, test_memory_size); } @@ -905,7 +943,7 @@ static uae_u8 *store_rel(uae_u8 *dst, uae_u8 mode, uae_u32 s, uae_u32 d, int ord *dst++ = mode | CT_RELATIVE_START_WORD; *dst++ = (diff >> 8) & 0xff; *dst++ = diff & 0xff; - } else if (d < LOW_MEMORY_END) { + } else if (d < 0x8000) { *dst++ = mode | CT_ABSOLUTE_WORD; *dst++ = (d >> 8) & 0xff; *dst++ = d & 0xff; @@ -1012,7 +1050,7 @@ static uae_u8 *store_mem(uae_u8 *dst, int storealways) continue; uaecptr addr = ah->addr; addr &= addressing_mask; - if (addr < LOW_MEMORY_END) { + if (addr < 0x8000) { *dst++ = CT_MEMWRITE | CT_ABSOLUTE_WORD; *dst++ = (addr >> 8) & 0xff; *dst++ = addr & 0xff; @@ -1054,6 +1092,10 @@ static uae_u32 gl(uae_u8 *p) { return (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | (p[3] << 0); } +static uae_u32 gw(uae_u8 *p) +{ + return (p[0] << 8) | (p[1] << 0); +} static bool load_file(const TCHAR *path, const TCHAR *file, uae_u8 *p, int size, int offset) { @@ -1397,6 +1439,19 @@ static int create_ea(uae_u16 *opcodep, uaecptr pc, int mode, int reg, struct ins static int imm_special; +static int handle_specials_preea(uae_u16 opcode, uaecptr pc, struct instr *dp) +{ + if (dp->mnemo == i_FTRAPcc) { + uae_u16 v = rand16(); + v &= ~7; + v |= imm_special; + put_word_test(pc, v); + imm_special++; + return 2; + } + return 0; +} + static int handle_specials_branch(uae_u16 opcode, uaecptr pc, struct instr *dp, int *isconstant) { // 68020 BCC.L is BCC.B to odd address if 68000/010 @@ -1405,6 +1460,12 @@ static int handle_specials_branch(uae_u16 opcode, uaecptr pc, struct instr *dp, return 0; } return -2; + } else if (dp->mnemo == i_FDBcc) { + // FDBcc jump offset + uae_u16 v = rand16(); + put_word_test(pc, v); + *isconstant = 16; + return 2; } return 0; } @@ -1421,16 +1482,65 @@ static int handle_specials_pack(uae_u16 opcode, uaecptr pc, struct instr *dp, in return 0; } +static void handle_specials_extra(uae_u16 opcode, uaecptr pc, struct instr *dp) +{ + // if MOVES to A7: change it to MOVES from A7. SSP modification would cause crash. + if (dp->mnemo == i_MOVES) { + uae_u16 extra = get_word_test(opcode_memory_start + 2); + if (!(extra & 0x800)) { + int reg = extra >> 12; + if (reg == 7 + 8) { + extra |= 0x800; + put_word_test(opcode_memory_start + 2, extra); + } + } + } + // cas undocumented (marked as zero in document) fields do something weird, for example + // setting bit 9 will make "Du" address register but results are not correct. + // so lets make sure unused zero bits are zeroed. + if (dp->mnemo == i_CAS) { + uae_u16 extra = get_word_test(opcode_memory_start + 2); + uae_u16 extra2 = extra; + extra &= (7 << 6) | (7 << 0); + if (extra != extra2) { + put_word_test(opcode_memory_start + 2, extra); + } + } + if (dp->mnemo == i_CAS2) { + uae_u16 extra = get_word_test(opcode_memory_start + 2); + uae_u16 extra2 = extra; + extra &= (7 << 6) | (7 << 0) | (15 << 12); + if (extra != extra2) { + put_word_test(opcode_memory_start + 2, extra); + } + extra = get_word_test(opcode_memory_start + 4); + extra2 = extra; + extra &= (7 << 6) | (7 << 0) | (15 << 12); + if (extra != extra2) { + put_word_test(opcode_memory_start + 4, extra); + } + + } + if (dp->mnemo == i_CHK2) { + uae_u16 extra = get_word_test(opcode_memory_start + 2); + uae_u16 extra2 = extra; + extra &= (15 << 12); + if (extra != extra2) { + put_word_test(opcode_memory_start + 2, extra); + } + + } +} static int handle_specials_stack(uae_u16 opcode, uaecptr pc, struct instr *dp, int *isconstant) { int offset = 0; - if (opcode == 0x4e73 || opcode == 0x4e74 || opcode == 0x4e75 || opcode == 0x4e77) { + if (dp->mnemo == i_RTE || dp->mnemo == i_RTD || dp->mnemo == i_RTS || dp->mnemo == i_RTR || dp->mnemo == i_UNLK) { uae_u32 v; uaecptr addr = regs.regs[8 + 7]; imm_special++; // RTE, RTD, RTS and RTR - if (opcode == 0x4e77) { + if (dp->mnemo == i_RTR) { // RTR v = imm_special; uae_u16 ccr = v & 31; @@ -1439,14 +1549,14 @@ static int handle_specials_stack(uae_u16 opcode, uaecptr pc, struct instr *dp, i addr += 2; offset += 2; *isconstant = imm_special >= (1 << (0 + 5)) * 4 ? 0 : -1; - } else if (opcode == 0x4e74) { + } else if (dp->mnemo == i_RTD) { // RTD v = imm_special >> 2; uae_u16 sr = v & 31; sr |= (v >> 5) << 12; put_word_test(addr + 4, sr); *isconstant = imm_special >= (1 << (4 + 5)) * 4 ? 0 : -1; - } else if (opcode == 0x4e73) { + } else if (dp->mnemo == i_RTE) { // RTE if (currprefs.cpu_model == 68000) { v = imm_special >> 2; @@ -1459,7 +1569,7 @@ static int handle_specials_stack(uae_u16 opcode, uaecptr pc, struct instr *dp, i // TODO 68010+ RTE } *isconstant = imm_special >= (1 << (4 + 5)) * 4 ? 0 : -1; - } else if (opcode == 0x4e75) { + } else if (dp->mnemo == i_RTS) { // RTS *isconstant = imm_special >= 256 ? 0 : -1; } @@ -1495,6 +1605,8 @@ static void execute_ins(uae_u16 opc, uaecptr endpc, uaecptr targetpc) && opw2 == 0x9908 ) printf(""); + if (regs.sr & 0x2000) + printf(""); // execute instruction SPCFLAG_TRACE = 0; @@ -1581,9 +1693,8 @@ static int isbranchinst(struct instr *dp) return 2; case i_DBcc: case i_FBcc: - return -1; case i_FDBcc: - return 1; + return -1; } return 0; } @@ -1610,6 +1721,8 @@ static int isunsupported(struct instr *dp) { case i_MOVE2C: case i_MOVEC2: + case i_FSAVE: + case i_FRESTORE: return 1; case i_RTE: if (cpu_lvl > 0) @@ -1623,7 +1736,7 @@ static int isunsupported(struct instr *dp) static uae_u8 last_exception[256]; static int last_exception_len; -static uae_u8 *save_exception(uae_u8 *p) +static uae_u8 *save_exception(uae_u8 *p, struct instr *dp) { uae_u8 *op = p; p++; @@ -1637,6 +1750,7 @@ static uae_u8 *save_exception(uae_u8 *p) p = store_rel(p, 0, opcode_memory_start, gl(sf + 2), 1); } } else if (cpu_lvl > 0) { + uae_u8 ccrmask = 0; uae_u16 frame = (sf[6] << 8) | sf[7]; // frame + vector offset *p++ = sf[6]; @@ -1653,12 +1767,19 @@ static uae_u8 *save_exception(uae_u8 *p) // effective address p = store_rel(p, 0, opcode_memory_start, gl(sf + 8), 1); break; - case 8: + case 4: // floating point unimplemented (68040/060) // fault/effective address p = store_rel(p, 0, opcode_memory_start, gl(sf + 8), 1); // FSLW or PC of faulted instruction p = store_rel(p, 0, opcode_memory_start, gl(sf + 12), 1); break; + case 0x0a: // 68020/030 address error. Only check SSW. + // SSW + p = store_reg(p, 0, 0, gw(sf + 0x0a), sz_word); + exception_stack_frame_size = 0x0c; + sf[8] = sf[9] = 0; + last_exception[8] = last_exception[9] = 0; + break; default: wprintf(_T("Unknown frame %04x!\n"), frame); abort(); @@ -1677,6 +1798,17 @@ static uae_u8 *save_exception(uae_u8 *p) return p; } +static uae_u16 get_ccr_ignore(struct instr *dp) +{ + uae_u16 ccrignoremask = 0; + if (cpu_lvl == 2 && test_exception == 5 && dp->mnemo == i_DIVS) { + // 68020/030 DIVS + Divide by Zero: V state is not stable. + ccrignoremask |= 2; // mask CCR=V + } + return ccrignoremask; +} + + static const TCHAR *sizes[] = { _T("B"), _T("W"), _T("L") }; static void test_mnemo(const TCHAR *path, const TCHAR *mnemo, int opcodesize, int fpuopcode) @@ -1702,7 +1834,6 @@ static void test_mnemo(const TCHAR *path, const TCHAR *mnemo, int opcodesize, in size = 0; } - xorshiftstate = 1; filecount = 0; struct mnemolookup *lookup = NULL; @@ -1715,15 +1846,22 @@ static void test_mnemo(const TCHAR *path, const TCHAR *mnemo, int opcodesize, in wprintf(_T("'%s' not found.\n"), mnemo); return; } + mn = lookup->mnemo; + xorshiftstate = lookup - lookuptab; const TCHAR *mns = lookup->name; if (fpuopcode >= 0) { + xorshiftstate = 128 + fpuopcode; mns = fpuopcodes[fpuopcode]; - if (opcodesize == 7) + if (opcodesize == 7) { mns = _T("FMOVECR"); - if (opcodesize == 8) + xorshiftstate = 128 + 64; + } else if (opcodesize == 8) { mns = _T("FMOVEM"); + xorshiftstate = 128 + 64 + 1; + } } + xorshiftstate += 256 * opcodesize; int pathlen = _tcslen(path); _stprintf(dir, _T("%s%s"), path, mns); @@ -1775,19 +1913,43 @@ static void test_mnemo(const TCHAR *path, const TCHAR *mnemo, int opcodesize, in registers[8 + 6] = opcode_memory_start - 0x100; registers[8 + 7] = test_memory_end - STACK_SIZE; + // 1.0 + fpuregisters[0].high = 0x3fff; + fpuregisters[0].low = 0x8000000000000000; + // -1.0 + fpuregisters[1].high = 0xbfff; + fpuregisters[1].low = 0x8000000000000000; + // 0.0 + fpuregisters[2].high = 0x0000; + fpuregisters[2].low = 0x0000000000000000; + // NaN + fpuregisters[3].high = 0x7fff; + fpuregisters[3].low = 0xffffffffffffffff; + // inf+ + fpuregisters[4].high = 0x7fff; + fpuregisters[4].low = 0x0000000000000000; + // inf- + fpuregisters[5].high = 0xffff; + fpuregisters[5].low = 0x0000000000000000; + + for (int i = 6; i < 8; i++) { + fpuregisters[i].high = rand16(); + fpuregisters[i].low = (((uae_u64)rand32()) << 32) | (rand32()); + } + uae_u32 cur_registers[MAX_REGISTERS]; for (int i = 0; i < MAX_REGISTERS; i++) { cur_registers[i] = registers[i]; } - floatx80 cur_fpuregisters[MAX_REGISTERS]; + floatx80 cur_fpuregisters[8]; for (int i = 0; i < 8; i++) { cur_fpuregisters[i] = fpuregisters[i]; } dst = storage_buffer; - memcpy(low_memory, low_memory_temp, 32768); - memcpy(high_memory, high_memory_temp, 32768); + memcpy(low_memory, low_memory_temp, low_memory_size); + memcpy(high_memory, high_memory_temp, high_memory_size); memcpy(test_memory, test_memory_temp, test_memory_size); full_format_cnt = 0; @@ -1877,12 +2039,14 @@ static void test_mnemo(const TCHAR *path, const TCHAR *mnemo, int opcodesize, in if (opc == 0xf228) printf(""); - if (subtest_count == 1568) + if (subtest_count == 3136) printf(""); uaecptr pc = opcode_memory_start + 2; + pc += handle_specials_preea(opc, pc, dp); + // create source addressing mode if (dp->suse) { int o = create_ea(&opc, pc, dp->smode, dp->sreg, dp, &isconstant_src, 0, fpuopcode, opcodesize); @@ -1920,6 +2084,8 @@ static void test_mnemo(const TCHAR *path, const TCHAR *mnemo, int opcodesize, in pc += o; } + handle_specials_extra(opc, pc, dp); + // if destination EA modified opcode dp = table68k + opc; @@ -2048,7 +2214,7 @@ static void test_mnemo(const TCHAR *path, const TCHAR *mnemo, int opcodesize, in int ok = 0; int cnt_stopped = 0; - uae_u16 last_sr = 0; + uae_u32 last_sr = 0; uae_u32 last_pc = 0; uae_u32 last_registers[MAX_REGISTERS]; floatx80 last_fpuregisters[8]; @@ -2105,18 +2271,15 @@ static void test_mnemo(const TCHAR *path, const TCHAR *mnemo, int opcodesize, in for (int i = 0; i < MAX_REGISTERS; i++) { regs.regs[i] = cur_registers[i]; } - regs.fpcr = 0; - regs.fpsr = 0; - regs.fpiar = 0; if (fpumode) { for (int i = 0; i < 8; i++) { regs.fp[i].fpx = cur_fpuregisters[i]; } regs.fpiar = regs.pc; // condition codes - regs.fpsr = (ccr & 15) << 24; + fpp_set_fpsr((ccr & 15) << 24); // precision and rounding - regs.fpcr = (ccr >> 4) << 4; + fpp_set_fpcr((ccr >> 4) << 4); } regs.sr = ccr | sr_mask; regs.usp = regs.regs[8 + 7]; @@ -2142,6 +2305,9 @@ static void test_mnemo(const TCHAR *path, const TCHAR *mnemo, int opcodesize, in if (regs.sr & 0x2000) prev_s_cnt++; + if (subtest_count == 928) + printf(""); + execute_ins(opc, pc - 2, branch_target); if (regs.s) @@ -2211,9 +2377,10 @@ static void test_mnemo(const TCHAR *path, const TCHAR *mnemo, int opcodesize, in last_registers[i] = d; } } - if (regs.sr != last_sr) { - dst = store_reg(dst, CT_SR, last_sr, regs.sr, -1); - last_sr = regs.sr; + uae_u32 ccrignoremask = get_ccr_ignore(dp) << 16; + if ((regs.sr | ccrignoremask) != last_sr) { + dst = store_reg(dst, CT_SR, last_sr, regs.sr | ccrignoremask, -1); + last_sr = regs.sr | ccrignoremask; } if (regs.pc != last_pc) { dst = store_rel(dst, CT_PC, last_pc, regs.pc, 0); @@ -2244,7 +2411,7 @@ static void test_mnemo(const TCHAR *path, const TCHAR *mnemo, int opcodesize, in dst = store_mem(dst, 0); if (test_exception) { *dst++ = CT_END | test_exception; - dst = save_exception(dst); + dst = save_exception(dst, dp); } else { *dst++ = CT_END; } @@ -2331,11 +2498,96 @@ static void test_mnemo(const TCHAR *path, const TCHAR *mnemo, int opcodesize, in cur_registers[8 + 6]--; cur_registers[8 + 7] -= 2; + for (int i = 0; i < 8; i++) { + cur_fpuregisters[i].high = rand16(); + cur_fpuregisters[i].low = (((uae_u64)rand32()) << 32) | (rand32()); + if (rand16() & 1) { + cur_fpuregisters[i].low |= 0x8000000000000000; + } + } } wprintf(_T("- %d tests\n"), subtest_count); } +static void test_mnemo_text(const TCHAR *path, const TCHAR *mode) +{ + TCHAR modetxt[100]; + int mnemo = -1; + int fpuopcode = -1; + int sizes = -1; + + _tcscpy(modetxt, mode); + my_trim(modetxt); + TCHAR *s = _tcschr(modetxt, '.'); + if (s) { + *s = 0; + TCHAR c = _totlower(s[1]); + if (c == 'b') + sizes = 6; + if (c == 'w') + sizes = 4; + if (c == 'l') + sizes = 0; + if (c == 'u') + sizes = 8; + if (c == 's') + sizes = 1; + if (c == 'x') + sizes = 2; + if (c == 'p') + sizes = 3; + if (c == 'd') + sizes = 5; + } + for (int j = 0; lookuptab[j].name; j++) { + if (!_tcsicmp(modetxt, lookuptab[j].name)) { + mnemo = j; + break; + } + } + if (mnemo < 0) { + if (_totlower(modetxt[0]) == 'f') { + if (!_tcsicmp(modetxt, _T("fmovecr"))) { + mnemo = i_FPP; + sizes = 7; + fpuopcode = 0; + } else if (!_tcsicmp(modetxt, _T("fmovem"))) { + mnemo = i_FPP; + sizes = 8; + fpuopcode = 0; + } else { + for (int i = 0; i < 64; i++) { + if (fpuopcodes[i] && !_tcsicmp(modetxt, fpuopcodes[i])) { + mnemo = i_FPP; + fpuopcode = i; + break; + } + } + } + } + if (mnemo < 0) { + wprintf(_T("Couldn't find '%s'\n"), modetxt); + return; + } + } + + if (mnemo >= 0 && sizes < 0) { + if (fpuopcode >= 0) { + for (int i = 0; i < 7; i++) { + test_mnemo(path, lookuptab[mnemo].name, i, fpuopcode); + } + } else { + test_mnemo(path, lookuptab[mnemo].name, 0, -1); + test_mnemo(path, lookuptab[mnemo].name, 4, -1); + test_mnemo(path, lookuptab[mnemo].name, 6, -1); + test_mnemo(path, lookuptab[mnemo].name, -1, -1); + } + } else { + test_mnemo(path, lookuptab[mnemo].name, sizes, fpuopcode); + } +} + static void my_trim(TCHAR *s) { int len; @@ -2530,12 +2782,21 @@ int __cdecl main(int argc, char *argv[]) opcode_memory = test_memory + test_memory_size / 2; opcode_memory_start = test_memory_start + test_memory_size / 2; + low_memory_size = test_low_memory_end; + if (low_memory_size < 0x8000) + low_memory_size = 0x8000; + + low_memory = (uae_u8 *)calloc(1, low_memory_size); + low_memory_temp = (uae_u8 *)calloc(1, low_memory_size); + high_memory = (uae_u8 *)calloc(1, high_memory_size); + high_memory_temp = (uae_u8 *)calloc(1, high_memory_size); + fill_memory(); TCHAR *lmem_rom_name = NULL; ini_getstring(ini, INISECTION, _T("low_rom"), &lmem_rom_name); if (lmem_rom_name && test_low_memory_start != 0xffffffff) { - if (load_file(NULL, lmem_rom_name, low_memory_temp, 32768, 0)) { + if (load_file(NULL, lmem_rom_name, low_memory_temp, low_memory_size, 0)) { wprintf(_T("Low test memory ROM loaded\n")); lmem_rom = 1; } @@ -2545,15 +2806,15 @@ int __cdecl main(int argc, char *argv[]) TCHAR *hmem_rom_name = NULL; ini_getstring(ini, INISECTION, _T("high_rom"), &hmem_rom_name); if (hmem_rom_name && test_high_memory_start != 0xffffffff) { - if (load_file(NULL, hmem_rom_name, high_memory_temp, 32768, -1)) { + if (load_file(NULL, hmem_rom_name, high_memory_temp, high_memory_size, -1)) { wprintf(_T("High test memory ROM loaded\n")); hmem_rom = 1; } } free(hmem_rom_name); - save_memory(path, _T("lmem.dat"), low_memory_temp, 32768); - save_memory(path, _T("hmem.dat"), high_memory_temp, 32768); + save_memory(path, _T("lmem.dat"), low_memory_temp, low_memory_size); + save_memory(path, _T("hmem.dat"), high_memory_temp, high_memory_size); save_memory(path, _T("tmem.dat"), test_memory_temp, test_memory_size); storage_buffer = (uae_u8 *)calloc(max_storage_buffer, 1); @@ -2657,102 +2918,46 @@ int __cdecl main(int argc, char *argv[]) while(modep) { int all = 0; - int mnemo = -1; - int fpuopcode = -1; - int sizes = -1; if (!_tcsicmp(mode, _T("all"))) { verbose = 0; for (int j = 1; lookuptab[j].name; j++) { - test_mnemo(path, lookuptab[j].name, 0, -1); - test_mnemo(path, lookuptab[j].name, 4, -1); - test_mnemo(path, lookuptab[j].name, 6, -1); - test_mnemo(path, lookuptab[j].name, -1, -1); + test_mnemo_text(path, lookuptab[j].name); } - // illg last. All currently selected CPU model's unsupported opcodes - // (illegal instruction, a-line and f-line) - test_mnemo(path, lookuptab[0].name, 0, -1); - test_mnemo(path, lookuptab[0].name, 4, -1); - test_mnemo(path, lookuptab[0].name, 6, -1); - test_mnemo(path, lookuptab[0].name, -1, -1); + // Illegal instructions last. All currently selected CPU model's unsupported opcodes + // (Generates illegal instruction, a-line or f-line exception) + test_mnemo_text(path, _T("ILLEGAL")); break; } - TCHAR *sp = _tcschr(modep, ','); - if (sp) - *sp++ = 0; - TCHAR modetxt[100]; - _tcscpy(modetxt, modep); - my_trim(modetxt); - TCHAR *s = _tcschr(modetxt, '.'); - if (s) { - *s = 0; - TCHAR c = _totlower(s[1]); - if (c == 'b') - sizes = 6; - if (c == 'w') - sizes = 4; - if (c == 'l') - sizes = 0; - if (c == 'u') - sizes = 8; - if (c == 's') - sizes = 1; - if (c == 'x') - sizes = 2; - if (c == 'p') - sizes = 3; - if (c == 'd') - sizes = 5; - } - for (int j = 0; lookuptab[j].name; j++) { - if (!_tcsicmp(modetxt, lookuptab[j].name)) { - mnemo = j; - break; - } - } - if (mnemo < 0) { - if (_totlower(modetxt[0]) == 'f') { - if (!_tcsicmp(modetxt, _T("fmovecr"))) { - mnemo = i_FPP; - sizes = 7; - fpuopcode = 0; - } else if (!_tcsicmp(modetxt, _T("fmovem"))) { - mnemo = i_FPP; - sizes = 8; - fpuopcode = 0; - } else { - for (int i = 0; i < 64; i++) { - if (fpuopcodes[i] && !_tcsicmp(modetxt, fpuopcodes[i])) { - mnemo = i_FPP; - fpuopcode = i; - break; - } - } + if (!_tcsicmp(mode, _T("fall"))) { + + verbose = 0; + test_mnemo_text(path, _T("FMOVECR")); + const TCHAR *prev = _T(""); + for (int j = 0; j < 64; j++) { + if (fpuopcodes[j] && _tcscmp(prev, fpuopcodes[j])) { + test_mnemo_text(path, fpuopcodes[j]); + prev = fpuopcodes[j]; } } - if (mnemo < 0) { - wprintf(_T("Couldn't find '%s'\n"), modetxt); - return 0; - } - } - - if (mnemo >= 0 && sizes < 0) { - if (fpuopcode >= 0) { - for (int i = 0; i < 8; i++) { - test_mnemo(path, lookuptab[mnemo].name, i, fpuopcode); + for (int j = 1; lookuptab[j].name; j++) { + if (lookuptab[j].name[0] == 'F' && _tcscmp(lookuptab[j].name, _T("FPP"))) { + test_mnemo_text(path, lookuptab[j].name); } - } else { - test_mnemo(path, lookuptab[mnemo].name, 0, -1); - test_mnemo(path, lookuptab[mnemo].name, 4, -1); - test_mnemo(path, lookuptab[mnemo].name, 6, -1); - test_mnemo(path, lookuptab[mnemo].name, -1, -1); } - } else { - test_mnemo(path, lookuptab[mnemo].name, sizes, fpuopcode); + test_mnemo_text(path, _T("FMOVEM")); + break; } + + TCHAR *sp = _tcschr(modep, ','); + if (sp) + *sp++ = 0; + + test_mnemo_text(path, modep); + modep = sp; } diff --git a/cputest/adis/decode_ea.c b/cputest/adis/decode_ea.c new file mode 100644 index 00000000..b44eb731 --- /dev/null +++ b/cputest/adis/decode_ea.c @@ -0,0 +1,402 @@ +/* + * Change history + * $Log: decode_ea.c,v $ + * Revision 3.1 09/12/11 Matt Hey + * Minor mod.: enter_ref() for immediate and PC memory indirect with index + * relocations is now ACC_UNKNOWN instead of access + * + * Revision 3.0 93/09/24 17:53:50 Martin_Apel + * New feature: Added extra 68040 FPU opcodes + * + * Revision 2.5 93/07/18 22:55:43 Martin_Apel + * *** empty log message *** + * + * Revision 2.4 93/07/11 21:38:04 Martin_Apel + * Major mod.: Jump table support tested and changed + * + * Revision 2.3 93/07/10 13:01:56 Martin_Apel + * Major mod.: Added full jump table support. Seems to work quite well + * + * Revision 2.2 93/07/08 22:27:46 Martin_Apel + * + * Minor mod.: Displacements below 4 used with pc indirect indexed are + * not entered into the symbol table anymore + * + * Revision 2.1 93/07/08 20:47:04 Martin_Apel + * Bug fix: Extended precision reals were printed wrong + * + * Revision 2.0 93/07/01 11:53:45 Martin_Apel + * *** empty log message *** + * + * Revision 1.12 93/07/01 11:38:28 Martin_Apel + * Minor mod.: PC relative addressing is now marked as such + * + * Revision 1.11 93/06/16 20:26:17 Martin_Apel + * Minor mod.: Added jump table support. UNTESTED !!! + * + * Revision 1.10 93/06/06 13:45:34 Martin_Apel + * Minor mod.: Replaced first_pass and read_symbols by pass1, pass2, pass3 + * + * Revision 1.9 93/06/03 18:22:12 Martin_Apel + * Minor mod.: Addressing relative to hunk end changed + * + */ + +#include "defs.h" + +/* static char rcsid [] = "$Id: decode_ea.c,v 3.0 93/09/24 17:53:50 Martin_Apel Exp $"; */ + +uint decode_ea (char *to, ushort mode, ushort reg, UWORD access, ushort first_ext) + +/* returns the number of extension words used for ea */ +{ +static ULONG maybe_jmptable_ref = UNSET; /* for jump table disassembly */ +ULONG ref; +register UWORD first_ext_w; + +first_ext_w = *(code + first_ext); +switch (mode) + { + /********************** data register direct ************************/ + + case 0: + if (pass3) + str_cpy (to, reg_names [reg]); + return (0); + + /********************* address register direct **********************/ + + case 1: + if (access & ACC_BYTE) + { + instr_bad = TRUE; + return (0); + } + if (pass3) + str_cpy (to, reg_names [reg + 8]); + return (0); + + /********************** address register indirect *******************/ + + case 2: + if (pass3) + indirect (to, (ushort)(reg + 8)); + else if ((*code & 0xfff8) == 0x4ed0) /* jmp (An) */ + { + if (!FLAGS_RELOC (maybe_jmptable_ref)) + enter_jmptab (maybe_jmptable_ref, 0); /* jmp table with word entries */ + else + { + /* Probably a jmp table of long relocs. The refs/labels pointed to + by the jmp table entries should already be entered but may not + be marked as code. */ + + while ((*(ULONG*)(flags + maybe_jmptable_ref - first_ref) & + ((FLAG_RELOC << 24) | (FLAG_RELOC << 16) | + (FLAG_RELOC << 8) | FLAG_RELOC)) == + ((FLAG_RELOC << 24) | (FLAG_RELOC << 16) | + (FLAG_RELOC << 8) | FLAG_RELOC)) + { + ref = *(ULONG*)(hunk_address + maybe_jmptable_ref - first_ref); + if (ODD (ref) || ref < first_ref || ref >= last_ref) + break; + enter_ref (ref, NULL, ACC_CODE); /* mark ref/label as code */ + maybe_jmptable_ref += 4; + } + } + } + return (0); + + /************ address register indirect post-increment **************/ + + case 3: + if (pass3) + post_inc (to, (ushort)(reg + 8)); + return (0); + + /************* address register indirect pre-decrement **************/ + + case 4: + if (pass3) + pre_dec (to, (ushort)(reg + 8)); + return (0); + + /************* address register indirect with displacement **********/ + + case 5: + if (try_small && reg == 4) + { + ref = (WORD)first_ext_w + a4_offset; + if (pass3) + gen_label_ref (to, ref); + else + enter_ref (ref, NULL, access); + } + else if (pass3) + disp_an (to, (ushort)(reg + 8), (ushort)first_ext_w); + return (1); + + /****************** address register indirect indexed ***************/ + + case 6: + if (first_ext_w & 0x100) + { + if (cpu68020) + return (full_extension (to, code + first_ext, mode, reg)); + else + { + instr_bad = TRUE; + return (0); + } + } + else + { + UWORD size = (first_ext_w >> 9) & 0x3; + + if (!cpu68020 && size != 0) /* Only size of 1 allowed for 68000 */ + { + instr_bad = TRUE; + return (0); + } + if (pass3) + { + /* To get the sign right */ + disp_an_indexed (to, (ushort)(reg + 8), + (BYTE)first_ext_w, + (ushort)(first_ext_w >> 12), + (ushort)(1 << size), + (first_ext_w & 0x0800) ? ACC_LONG : ACC_WORD); + } + return (1); + } + + /************************* Mode 7 with submodes *********************/ + + case 7: + switch (reg) + { + /*********************** absolute short *********************/ + + case 0: + if (pass3) + { + to = format_ulx (to, (WORD)first_ext_w); + *to++ = '.'; + *to++ = 'w'; + *to = 0; + } + return (1); + + /*********************** absolute long **********************/ + + case 1: + ref = *(ULONG*)(code + first_ext); + if (FLAGS_RELOC (current_ref + first_ext * 2)) + { + if (pass3) + /* This reference is relocated and thus needs a label */ + gen_label_ref (to, ref); + else + { + enter_ref (ref, NULL, access); + /* + if (EVEN (ref) && ref >= first_ref && ref < last_ref) + maybe_jmptable_ref = ref; + */ + } + } + else if (pass3) + { + to = format_ulx (to, ref); + if (!optimize) + { + *to++ = '.'; + *to++ = 'l'; + *to = 0; + } + } + return (2); + + /************************** d16(PC) *************************/ + + case 2: +/* It's possible, that a program accesses its hunk structure PC relative, + thus it generates a reference to a location outside valid code addresses */ + + /* A neg displacement can make ref neg if out of bounds. */ + ref = current_ref + ((ULONG)first_ext << 1) + (WORD)first_ext_w; + if (pass3) + { + if (!old_style) + *to++ = '('; + if ((LONG)ref < (LONG)first_ref) + { + to = gen_label_ref (to, first_ref); + *to++ = '-'; + to = format_lx (to, (LONG)first_ref - (LONG)ref); + } + else if (ref >= last_ref) + { + to = gen_label_ref (to, last_ref - 2); + *to++ = '+'; + to = format_lx (to, ref - last_ref + 2); + } + else + to = gen_label_ref (to, ref); + if (old_style) + *to++ = '('; + else + *to++ = ','; + to = str_cpy (to, reg_names [PC]); + *to++ =')'; + *to = 0; + } + else if ((LONG)ref >= (LONG)first_ref && (LONG)ref < (LONG)last_ref) + { + enter_ref (ref, NULL, access); + if (EVEN (ref)) + maybe_jmptable_ref = ref; + } + return (1); + + /***************** PC memory indirect with index ************/ + + case 3: + if (first_ext_w & 0x0100) + { + /* long extension word */ + if (cpu68020) + return (full_extension (to, code + first_ext, mode, reg)); + else + { + instr_bad = TRUE; + return (0); + } + } + else + { + UWORD size = (first_ext_w >> 9) & 0x3; + + if (!cpu68020 && size != 0) /* Only size of 1 allowed for 68000 */ + { + instr_bad = TRUE; + return (0); + } + /* A neg displacement can make ref neg if out of bounds. */ + ref = current_ref + ((ULONG)first_ext << 1) + (BYTE)first_ext_w; + if (pass3) + disp_pc_indexed (to, ref, (BYTE)first_ext_w, + (ushort)(first_ext_w >> 12), + (ushort)(1 << size), + (first_ext_w & 0x0800) ? ACC_LONG : ACC_WORD); + else if ((LONG)ref >= (LONG)first_ref && (LONG)ref < (LONG)last_ref) + { + if (*code == 0x4efb) /* Check for JMP (d8,PC,Xn) */ + { + enter_jmptab (maybe_jmptable_ref, (ULONG)((BYTE)first_ext_w) + 2); + } + else + { + enter_ref (ref, NULL, access); + if (EVEN (ref)) + maybe_jmptable_ref = ref; + } + } + return (1); + } + + /************************ immediate *************************/ + + case 4: + if (access & ACC_BYTE) + { + if (pass3) + { + *to++ = '#'; + if (access & ACC_SIGNED) + format_x (to, (BYTE)first_ext_w); + else + format_ux (to, (UBYTE)first_ext_w); + } + return (1); + } + else if (access & ACC_WORD) + { + if (pass3) + { + *to++ = '#'; + if (access & ACC_SIGNED) + format_x (to, (WORD)first_ext_w); + else + format_ux (to, (UWORD)first_ext_w); + } + return (1); + } + else if (access & ACC_LONG) + { + ref = *(ULONG*)(code + first_ext); + if (FLAGS_RELOC (current_ref + first_ext * 2)) + { + if (pass2) + { + enter_ref (ref, NULL, ACC_UNKNOWN); /* data type and size is unknown */ + if (EVEN (ref) && ref >= first_ref && ref < last_ref) + maybe_jmptable_ref = ref; + } + else + { + /* This reference is relocated and thus needs a label */ + *to++ = '#'; + *to++ = '('; + to = gen_label_ref (to, ref); + *to++ = ')'; + *to++ = 0; + } + } + else if (pass3) + { + *to++ = '#'; + if (access & ACC_SIGNED) + format_lx (to, (LONG)ref); + else + format_ulx (to, ref); + } + return (2); + } + else if (access & ACC_DOUBLE) + { + if (pass3) + { + sprintf (to, "#$%lx%08lx", *(ULONG*)(code + first_ext), + *(ULONG*)(code + first_ext + 2)); + } + return (4); + } + else if (access & ACC_EXTEND) + { + if (pass3) + { + sprintf (to, "#$%lx%08lx%08lx", *(ULONG*)(code + first_ext), + *(ULONG*)(code + first_ext + 2), + *(ULONG*)(code + first_ext + 4)); + } + return (6); + } +#ifdef DEBUG + else + { + fprintf (stderr, "WARNING: Unknown immediate addressing size at %lx\n", current_ref); + } +#endif + break; + default: + /* Should not occur, as it should be caught by the submode test in disasm.c */ + instr_bad = TRUE; +#ifdef DEBUG + fprintf (stderr, "WARNING: Illegal submode at %lx\n", current_ref); +#endif + } + break; + } +return (0); +} diff --git a/cputest/adis/defs.h b/cputest/adis/defs.h new file mode 100644 index 00000000..63c24544 --- /dev/null +++ b/cputest/adis/defs.h @@ -0,0 +1,522 @@ +/* + * Change history + * $Log: defs.h,v $ + * Revision 3.0 93/09/24 17:54:36 Martin_Apel + * New feature: Added extra 68040 FPU opcodes + * + * Revision 2.4 93/07/18 22:57:05 Martin_Apel + * *** empty log message *** + * + * Revision 2.3 93/07/11 21:40:10 Martin_Apel + * Major mod.: Jump table support tested and changed + * + * Revision 2.2 93/07/10 13:02:39 Martin_Apel + * Major mod.: Added full jump table support. Seems to work quite well + * + * Revision 2.1 93/07/08 20:50:47 Martin_Apel + * Minor mod.: Added print_flags for debugging purposes + * + * Revision 2.0 93/07/01 11:55:04 Martin_Apel + * *** empty log message *** + * + * Revision 1.30 93/07/01 11:46:54 Martin_Apel + * Minor mod.: Prepared for tabs instead of spaces + * + * Revision 1.29 93/06/19 12:12:20 Martin_Apel + * Major mod.: Added full 68030/040 support + * + * Revision 1.28 93/06/16 20:31:52 Martin_Apel + * Minor mod.: Removed #ifdef FPU_VERSION and #ifdef MACHINE68020 + * Minor mod.: Added variables for 68030 / 040 support + * + * Revision 1.27 93/06/06 13:48:45 Martin_Apel + * Minor mod.: Added preliminary support for jump tables recognition + * Minor mod.: Replaced first_pass and read_symbols by pass1, pass2, pass3 + * + * Revision 1.26 93/06/06 00:16:26 Martin_Apel + * Major mod.: Added support for library/device disassembly (option -dl) + * + * Revision 1.25 93/06/04 11:57:34 Martin_Apel + * New feature: Added -ln option for generation of ascending label numbers + * + * Revision 1.24 93/06/03 20:31:01 Martin_Apel + * New feature: Added -a switch to generate comments for file offsets + * + * Revision 1.23 93/06/03 18:28:15 Martin_Apel + * Minor mod.: Added new prototypes an variables for hunk-handling routines. + * Minor mod.: Remove temporary files upon exit (even with CTRL-C). + * + */ + +#define _CRT_SECURE_NO_WARNINGS + +#if 0 +#include +#endif + +#include +#include +#include + +#ifdef MCH_AMIGA +#ifndef AMIGA +#define AMIGA +#endif +#endif + +#ifdef DEBUG +#define PRIVATE +#else +#define PRIVATE static +#endif + +typedef unsigned char UBYTE; +typedef unsigned short UWORD; +typedef unsigned long ULONG; + +typedef signed char BYTE; +typedef signed short WORD; +typedef signed long LONG; + +typedef signed short BOOL; +#define TRUE 1 +#define FALSE 0 + +#if !defined(__GNUC__) +/* Already defined in sys/types.h for GCC */ +typedef unsigned int uint; +typedef unsigned short ushort; +#endif +typedef unsigned char uchar; + +/* $Id: defs.h,v 3.0 93/09/24 17:54:36 Martin_Apel Exp $ */ + +struct opcode_entry + { + uint (*handler) (struct opcode_entry*); + UBYTE modes; /* addressing modes allowed for this opcode */ + UBYTE submodes; /* addressing submodes of mode 7 allowed for this opcode */ + UWORD chain; /* if another opcode is possible for this bit pattern, */ + /* this is the index of another entry in opcode_table. */ + /* Otherwise it's zero */ + char *mnemonic; + UWORD param; /* given to handler () */ + UWORD access; /* data type of instruction access (ACC_ flags) */ + }; + +struct opcode_sub_entry + { + uint (*handler) (struct opcode_sub_entry*); + char *mnemonic; + UWORD param; /* given to handler () */ + UWORD access; /* data type of instruction access (ACC_ flags) */ + }; + +#define TRANSFER 0 /* The handler didn't handle this opcode */ + /* Transfer to next in chain */ +/* Param values */ +/* MOVEM direction */ +#define REG_TO_MEM 0 +#define MEM_TO_REG 1 +/* Bitfield instructions */ +#define DATADEST 0 +#define DATASRC 1 +#define SINGLEOP 2 +/* MOVE to or from SR, CCR */ +#define TO_CCR 0 +#define FROM_CCR 1 +#define TO_SR 2 +#define FROM_SR 3 +/* Extended precision and BCD instructions */ +#define NO_ADJ 0 +#define ADJUST 1 + +/* Bit masks */ +#define EA_MODE 0x038 /* Bits 5 - 3 */ +#define EA_REG 0x007 /* Bits 2 - 0 */ +#define REG2 0xe00 /* Bits 11 - 9 */ +#define OP_MODE 0x1c0 /* Bits 8 - 6 */ + +/* Shift values */ +#define MODE_SHIFT 3 +#define REG2_SHIFT 9 +#define OP_MODE_SHIFT 6 + +#define MODE_NUM(x) ((UWORD)(((x) >> 3) & 0x7)) +#define REG_NUM(x) ((UWORD)((x) & EA_REG)) + +#define USE_SIGN TRUE +#define NO_SIGN FALSE +#define USE_LABEL TRUE +#define NO_LABEL FALSE +#define USE_COMMENT TRUE +#define NO_COMMENT FALSE + +#define DEF_BUF_SIZE (16L * 1024L) + +enum + { + SR, CCR, USP, SFC, DFC, CACR, VBR, CAAR, MSP, ISP, TC, + ITT0, ITT1, DTT0, DTT1, MMUSR, URP, SRP, TT0, TT1, CRP + }; + +#define PC (ushort)16 /* index into reg_names array */ + +/* Access types for reference table. */ +#define ACC_BYTE (UWORD)0x0001 /* referenced as byte */ +#define ACC_WORD (UWORD)0x0002 /* referenced as word */ +#define ACC_LONG (UWORD)0x0004 /* referenced as long or fp single (4 bytes) */ +#define ACC_DOUBLE (UWORD)0x0008 /* referenced as fp double (8 bytes) */ +#define ACC_EXTEND (UWORD)0x0010 /* referenced as fp extended (12 bytes) */ +#define ACC_SIGNED (UWORD)0x0020 +#define ACC_DATA (UWORD)0x0040 /* referenced as data but size unknown */ +#define ACC_CODE (UWORD)0x0080 /* referenced as code */ +#define ACC_UNKNOWN (UWORD)0x0100 /* accessed but unknown if code or data */ +/* ... */ +#define ACC_INACTIVE (UWORD)0x4000 /* This label is temporarily deactivated */ +#define ACC_NEW (UWORD)0x8000 /* ref is new and easily deleted */ + +#define ACC_SBYTE ACC_BYTE|ACC_SIGNED /* shortcut for signed byte */ +#define ACC_SWORD ACC_WORD|ACC_SIGNED /* shortcut for signed word */ +#define ACC_SLONG ACC_LONG|ACC_SIGNED /* shortcut for signed long */ + +/* Flags (UBYTE) */ +#define FLAG_BYTE 0x01 /* data size is byte */ +#define FLAG_WORD 0x02 /* data size is word */ +#define FLAG_LONG 0x04 /* data size is long */ +#define FLAG_SIGNED 0x08 /* data is signed */ +#define FLAG_RELOC 0x10 /* data is relocatable */ +#define FLAG_STRING 0x20 /* data is a string */ +#define FLAG_TABLE 0x40 /* data is a table */ +#define FLAG_CODE 0x80 /* data is code */ + +#define FLAGS_BYTE(ref) (*(flags + (ref) - first_ref) & FLAG_BYTE) +#define FLAGS_WORD(ref) (*(flags + (ref) - first_ref) & FLAG_WORD) +#define FLAGS_LONG(ref) (*(flags + (ref) - first_ref) & FLAG_LONG) +#define FLAGS_SIGNED(ref) (*(flags + (ref) - first_ref) & FLAG_SIGNED) +#define FLAGS_RELOC(ref) (*(flags + (ref) - first_ref) & FLAG_RELOC) +#define FLAGS_CODE(ref) (*(flags + (ref) - first_ref) & FLAG_CODE) +#define FLAGS_STRING(ref) (*(flags + (ref) - first_ref) & FLAG_STRING) +#define FLAGS_BAD(ref) (*(flags + (ref) - first_ref) &\ + (FLAG_CODE | FLAG_RELOC)) +#define FLAGS_ANY(ref) (*(flags + (ref) - first_ref)) +#define FLAGS_NONE(ref) (!FLAGS_ANY(ref)) + +#define FLAGS_BYTE_P(ptr) (*(ptr) & FLAG_BYTE) +#define FLAGS_WORD_P(ptr) (*(ptr) & FLAG_WORD) +#define FLAGS_LONG_P(ptr) (*(ptr) & FLAG_LONG) +#define FLAGS_SIGNED_P(ptr) (*(ptr) & FLAG_SIGNED) +#define FLAGS_RELOC_P(ptr) (*(ptr) & FLAG_RELOC) +#define FLAGS_CODE_P(ptr) (*(ptr) & FLAG_CODE) +#define FLAGS_STRING_P(ptr) (*(ptr) & FLAG_STRING) +#define FLAGS_BAD_P(ptr) (*(ptr) & (FLAG_CODE | FLAG_RELOC)) +#define FLAGS_ANY_P(ptr) (*(ptr)) + +/* Marker for jump-tables */ +#ifdef DEBUG +#define UNSET 0xffffffffL +#else +#define UNSET 0L +#endif + +#define ODD(x) ((x) & 1) +#define EVEN(x) (!ODD(x)) + +/* More efficient use of disassembler pass variables than 3 booleans */ +#define set_pass1 (pass = 0) +#define set_pass2 (pass = 1) +#define set_pass3 (pass = -1) +#define pass1 (pass == 0) +#define pass2 (pass > 0) +#define pass3 (pass < 0) + +extern UBYTE *hunk_address; +extern UBYTE *flags; /* UBYTE array of flags describing data. See Flags above */ +extern UWORD *code; + +/* Refs are total offsets of the program starting with lowest numbered hunk. + hunk_offset = current_ref - first_ref; + data_address = *hunk_address + current_ref - first_ref; */ + +extern ULONG current_ref; /* like Program Counter (PC) but with refs */ +extern ULONG first_ref; /* start ref of current hunk */ +extern ULONG last_ref; /* last ref of current hunk */ +extern ULONG total_size; /* total program size in bytes */ +extern ULONG current_hunk; /* hunk number of current hunk */ +/* The following point to a table (array) of hunk attributes indexed by hunk number */ +extern ULONG *hunk_start, + *hunk_end, + *hunk_offset, /* hunk f_offset */ + *hunk_memtype; /* hunk memory type */ + +extern char *conditions []; +extern char *reg_names []; +extern char *special_regs []; +extern char opcode []; +extern char src []; +extern char dest []; +extern char spaces []; + +extern ULONG f_offset; /* file offset */ +extern FILE *in, + *out, + *tmp_f; +extern char *in_buf, + *out_buf; +extern char *input_filename; +extern char *output_filename; +extern char *fd_filename; + +extern int buf_size; +extern long a4_offset; +extern BOOL try_small; +extern BOOL instr_bad; +extern BOOL instr_end; +extern char pass; +extern char space_char; +extern char comment; +extern BOOL optimize; +extern BOOL branch_sizes; +extern BOOL verbose; +extern BOOL print_illegal_instr_offset; +extern BOOL single_file; +extern BOOL ascending_label_numbers; +extern BOOL disasm_as_lib; +extern BOOL old_style; +extern BOOL cpu68020, + cpu68030, + cpu68040, + cpu68060, + cpuCF, + fpu68881; + +extern BOOL ROMTagFound; +extern UBYTE ROMTagType; +extern ULONG ROMTagRef; +extern ULONG InitTableRef; +extern ULONG FuncTableRef; +extern ULONG DataTableRef; + +extern short cpu68020_disabled []; +extern short cpu68030_disabled []; +extern short cpu68040_disabled []; +extern short cpu68060_disabled []; +extern short cpuCF_disabled []; +extern short fpu68881_disabled []; + +extern int OPCODE_COL; +extern int PARAM_COL; +extern int COMMENT_COL; +extern int MAX_STR_COL; + + +/* Prototypes */ + +/* analyze.c */ +void analyze_code (UBYTE *seg); + +/* decode_ea.c */ +uint decode_ea (char *to, ushort mode, ushort reg, UWORD access, ushort first_ext); + +/* disasm_code.c */ +uint disasm_instr (UWORD *instr, char*); +void disasm_code (UBYTE *seg, ULONG seg_size); + +/* disasm_data.c */ +void disasm_data (UBYTE *seg, ULONG seg_size); +void disasm_bss (void); + +/* main.c */ +int main (int argc, char *argv []); +void parse_args (int argc, char *argv []); +#ifdef DEBUG +void usage (void); +#endif +void open_files (void); +void close_files (void); +void open_output_file (void); +void close_output_file (void); +void ExitADis (void); +#ifdef DEBUG +void check_consistency (void); +#endif + +/* util.c */ +char *str_cpy (char *dest, const char *src); +char *str_cat (char *dest, const char *src); +BOOL is_str (char *maybe_string, uint max_len); +int str_len (char *maybe_string, uint max_len); +void emit (char *string); +void col_emit (char *string); + +char *format_ulx (char *to, ULONG val); +char *format_lx (char *to, ULONG val); +char *format_ulx_no_dollar (char *to, ULONG val); +char *format_ulx_digits (char *to, ULONG val, uint digits); +/* Processing .l is as fast or faster than .w for 68020+. */ +/* format_ulx () can handle UWORD values thus define below. */ +#define format_ux(to,val) format_ulx(to,val) +/* format_lx () can handle WORD (and BYTE) values thus define below. */ +#define format_x(to,val) format_lx(to,val) +/* format_ulx_no_dollar () can handle UWORD values thus define below. */ +#define format_ux_no_dollar(to,val) format_ulx_no_dollar(to,val) + +void format_reg_list (char *to, UWORD list, BOOL to_mem, ushort reglist_offset); +char *immed (char *to, ULONG val); +void pre_dec (char *to, ushort reg_num); +void post_inc (char *to, ushort reg_num); +void indirect (char *to, ushort reg_num); +void disp_an (char *to, ushort reg_num, WORD disp); +void disp_an_indexed (char *to, ushort an, BYTE disp, ushort index_reg, + ushort scale, ushort size); +void disp_pc_indexed (char *to, ULONG ref, BYTE disp, ushort index_reg, + ushort scale, ushort size); +uint full_extension (char *to, UWORD *instr, ushort mode, ushort reg); +char *gen_xref (char *to, ULONG address); +char *gen_label_ref (char *to, ULONG ref); +char *gen_label (char *to, ULONG ref); +char *format_line (char *to, BOOL commented, int instr_words); +void assign_label_names (void); + +/* hunks.c */ +BOOL readfile (void); +void read_hunk_header (void); +void read_hunk_unit (void); +BOOL read_hunk_code (void); +BOOL read_hunk_data (void); +BOOL read_hunk_bss (void); +void process_hunks (UBYTE *seg); +BOOL read_hunk_symbol (void); +BOOL read_hunk_reloc16 (UBYTE *seg); +BOOL read_hunk_reloc32 (UBYTE *seg); + +/* refs.c */ +BOOL init_ref_table (ULONG size); +void kill_ref_table (void); +void enter_ref (ULONG ref, char *name, UWORD access_type); +ULONG ext_enter_ref (ULONG ref, ULONG hunk, char *name, UWORD access_type); +BOOL find_ref (ULONG ref, char **name, UWORD *access_type); +BOOL find_active_ref (ULONG ref, char **name, UWORD *access_type); +ULONG next_ref (ULONG from, ULONG to, UWORD *access_type); +ULONG next_active_ref (ULONG from, ULONG to, UWORD *access_type); +void deactivate_refs (ULONG from, ULONG to); +void save_new_refs (void); +void delete_new_refs (void); + +/* mem.c */ +void *alloc_mem (ULONG size); +void free_mem (void *buffer); + +/* user_defined.c */ +void predefine_label (ULONG address, UWORD access); +void add_predefined_labels (void); + +#ifdef DEBUG +void print_ref_table (ULONG from, ULONG to); +void print_active_table (ULONG from, ULONG to); +void check_active_table (void); +#endif + +/* opcodes.c */ +extern struct opcode_entry opcode_table []; + +/* opcode_handler.c */ + +uint EA_to_Rn (struct opcode_entry *op); +uint Rn_to_EA (struct opcode_entry *op); +uint op1 (struct opcode_entry *op); +uint op1_end (struct opcode_entry *op); +uint imm_b (struct opcode_entry *op); +uint imm_w (struct opcode_entry *op); +uint imm_l (struct opcode_entry *op); +uint quick (struct opcode_entry *op); +uint bit_reg (struct opcode_entry *op); +uint bit_imm (struct opcode_entry *op); +uint move (struct opcode_entry *op); +uint movem (struct opcode_entry *op); +uint moveq (struct opcode_entry *op); +uint srccr (struct opcode_entry *op); +uint special (struct opcode_entry *op); +uint illegal (struct opcode_entry *op); +uint invalid (struct opcode_entry *op); +uint branch (struct opcode_entry *op); +uint dbranch (struct opcode_entry *op); +uint shiftreg (struct opcode_entry *op); +uint op2_bcdx (struct opcode_entry *op); +uint scc (struct opcode_entry *op); +uint exg (struct opcode_entry *op); +uint movesrccr (struct opcode_entry *op); +uint cmpm (struct opcode_entry *op); +uint movep (struct opcode_entry *op); +uint bkpt (struct opcode_entry *op); +uint muldivl (struct opcode_entry *op); +uint bitfield (struct opcode_entry *op); +uint trapcc (struct opcode_entry *op); +uint chkcmp2 (struct opcode_entry *op); +uint cas (struct opcode_entry *op); +uint cas2 (struct opcode_entry *op); +uint moves (struct opcode_entry *op); +uint link_l (struct opcode_entry *op); +uint move16 (struct opcode_entry *op); +uint cache (struct opcode_entry *op); +uint mov3q (struct opcode_entry *op); /* ColdFire */ +uint invalid2 (struct opcode_sub_entry *op); /* for mmu & fpu subtables */ + +#define SNG_ALL 1 /* Single operand syntax allowed */ + +/* opcodes_fpu.c */ +extern struct opcode_sub_entry fpu_opcode_table []; +extern char *xfer_size []; +extern UWORD sizes []; +extern char *fpu_conditions []; + +/* opcode_handler_fpu.c */ +uint fpu (struct opcode_entry *op); +uint fscc (struct opcode_entry *op); +uint fbranch (struct opcode_entry *op); +uint ftrapcc (struct opcode_entry *op); +uint fdbranch (struct opcode_entry *op); + +uint std_fpu (struct opcode_sub_entry *op); +uint fsincos (struct opcode_sub_entry *op); +uint ftst (struct opcode_sub_entry *op); + + +/* opcodes_mmu.c */ +extern struct opcode_sub_entry mmu_opcode_table []; + +/* opcode_handler_mmu.c */ +uint plpa60 (struct opcode_entry *op); +uint pflush40 (struct opcode_entry *op); +uint ptest40 (struct opcode_entry *op); +uint mmu30 (struct opcode_entry *op); +uint ptest30 (struct opcode_entry *op); + +uint pfl_or_ld (struct opcode_sub_entry *op); +uint pflush30 (struct opcode_sub_entry *op); +uint pmove30 (struct opcode_sub_entry *op); + +/* amiga.c */ +BOOL user_aborted_analysis (void); +void delete_tmp_files (void); +#ifdef AMIGA +void use_host_cpu_type (void); +ULONG req_off (void); +void req_on (ULONG oldwindowptr); +#endif + +/* version.c */ +void print_version (void); + +/* jmptab.c */ +void free_jmptab_list (void); +void enter_jmptab (ULONG start, ULONG offset); +BOOL next_code_ref_from_jmptab (UBYTE *seg); +/* BOOL invalidate_last_jmptab_entry (void); */ +BOOL find_and_format_jmptab (char *to, WORD current_w); +#ifdef DEBUG +void print_jmptab_list (void); +#endif + +/* library.c */ +void enter_library_refs (UBYTE *seg); diff --git a/cputest/adis/globals.c b/cputest/adis/globals.c new file mode 100644 index 00000000..79d472f9 --- /dev/null +++ b/cputest/adis/globals.c @@ -0,0 +1,327 @@ +/* + * Change history + * $Log: globals.c,v $ + * + * Revision 3.1 09/10/19 Matt_Hey + * New feature: Added cpu68060 support + * + * Revision 3.0 93/09/24 17:54:00 Martin_Apel + * New feature: Added extra 68040 FPU opcodes + * + * Revision 2.1 93/07/18 22:55:57 Martin_Apel + * *** empty log message *** + * + * Revision 2.0 93/07/01 11:54:00 Martin_Apel + * *** empty log message *** + * + * Revision 1.15 93/07/01 11:39:52 Martin_Apel + * Minor mod.: Prepared for tabs instead of spaces. + * Minor mod.: Added 68030 opcodes to disable list + * + * Revision 1.14 93/06/19 12:08:38 Martin_Apel + * Major mod.: Added full 68030/040 support + * + * Revision 1.13 93/06/16 20:28:04 Martin_Apel + * Minor mod.: Removed #ifdef FPU_VERSION and #ifdef MACHINE68020 + * Minor mod.: Added variables for 68030 / 040 support + * + * Revision 1.12 93/06/06 13:46:34 Martin_Apel + * Minor mod.: Replaced first_pass and read_symbols by pass1, pass2, pass3 + * + * Revision 1.11 93/06/06 00:11:41 Martin_Apel + * Major mod.: Added support for library/device disassembly (option -dl) + * + * Revision 1.10 93/06/04 11:50:40 Martin_Apel + * New feature: Added -ln option for generation of ascending label numbers + * + * Revision 1.9 93/06/03 20:27:16 Martin_Apel + * New feature: Added -a switch to generate comments for file offsets + * + * Revision 1.8 93/06/03 18:31:10 Martin_Apel + * Minor mod.: Added hunk_end array + * Minor mod.: Remove temporary files upon exit (even with CTRL-C) + * + */ + +#include "defs.h" + +/* static char rcsid [] = "$Id: globals.c,v 3.0 93/09/24 17:54:00 Martin_Apel Exp $"; */ + +UBYTE *hunk_address; +UBYTE *flags; +UWORD *code; +ULONG current_ref; +ULONG first_ref; +ULONG last_ref; +ULONG total_size; +ULONG current_hunk; +ULONG *hunk_start = NULL, + *hunk_end = NULL, + *hunk_offset = NULL, + *hunk_memtype = NULL; + +ULONG f_offset; +FILE *in = NULL, + *out = NULL, + *tmp_f = NULL; +char *in_buf = NULL, + *out_buf = NULL; +char *input_filename = NULL; +char *output_filename = NULL; +char *fd_filename = NULL; + +/* Variables for options */ + +int OPCODE_COL = 3; /* def column instructions */ +int PARAM_COL = 12; /* def column paramaters */ +int COMMENT_COL = 40; /* def column comments */ +int MAX_STR_COL = 77; /* max column for dc.b string */ + +int buf_size = DEF_BUF_SIZE; /* -f */ + +/* Try to resolve addressing used by many compilers in small mode. */ +/* (Addressing relative to A4) */ +long a4_offset = -1; +BOOL try_small = FALSE; /* -b */ + +BOOL single_file = TRUE; +BOOL print_illegal_instr_offset = FALSE; /* -i */ +BOOL old_style = FALSE; +BOOL cpu68020 = FALSE, /* -m2 */ + cpu68030 = FALSE, /* -m3 */ + cpu68040 = FALSE, /* -m4 */ + cpu68060 = FALSE, /* -m6 */ + cpuCF = FALSE, + fpu68881 = FALSE; /* -m8 */ +BOOL disasm_as_lib = FALSE; /* -l */ +BOOL ascending_label_numbers = FALSE; /* -dn */ +BOOL verbose = FALSE; +BOOL optimize = TRUE; +BOOL branch_sizes = TRUE; +BOOL instr_bad; +BOOL instr_end; +char pass; +char space_char = ' '; /* space or tab for column seperator */ +char comment = 0; /* -a */ + +ULONG InitTableRef = 0; +ULONG FuncTableRef = 0; +ULONG DataTableRef = 0; +ULONG ROMTagRef = 0; +BOOL ROMTagFound = FALSE; +UBYTE ROMTagType; + +char spaces [44]; /* storage for leading spaces before instructions */ +char opcode [20]; /* storage for instruction name (mnemonic) */ +char src [200]; /* storage for source op */ +char dest [200]; /* storage for destination op */ + +char *conditions [] = + { + "t", + "f", + "hi", + "ls", + "cc", + "cs", + "ne", + "eq", + "vc", + "vs", + "pl", + "mi", + "ge", + "lt", + "gt", + "le" + }; + +char *reg_names [] = + { + "d0", + "d1", + "d2", + "d3", + "d4", + "d5", + "d6", + "d7", + "a0", + "a1", + "a2", + "a3", + "a4", + "a5", + "a6", + "sp", + "pc", /* Start at offset 17 */ + "fp0", + "fp1", + "fp2", + "fp3", + "fp4", + "fp5", + "fp6", + "fp7" + }; + +char *special_regs [] = + { + "sr", /* 0 */ + "ccr", /* 1 */ + "usp", /* 2 */ + "sfc", /* 3 */ + "dfc", /* 4 */ + "cacr", /* 5 */ + "vbr", /* 6 */ + "caar", /* 7 */ + "msp", /* 8 */ + "isp", /* 9 */ + "tc", /* 10 */ + "itt0", /* 11 */ + "itt1", /* 12 */ + "dtt0", /* 13 */ + "dtt1", /* 14 */ + "mmusr", /* 15 */ + "urp", /* 16 */ + "srp", /* 17 */ + "tt0", /* 18 */ + "tt1", /* 19 */ + "crp" /* 20 */ + }; + +/**********************************************************************/ +/* When the program is compiled for use on a 68020 system, */ +/* 68020 instructions disassembly can be switched off */ +/* via a command line switch. */ +/* Then those following instructions are marked as illegal */ +/**********************************************************************/ + +short cpu68020_disabled [] = + { + 3, /* CHK2, CMP2 */ + 11, /* CHK2, CMP2 */ + 19, /* CHK2, CMP2 */ + 27, /* CALLM */ + 43, /* CAS */ + 51, /* CAS */ + 56, /* MOVES */ + 57, /* MOVES */ + 58, /* MOVES */ + 59, /* CAS */ + 260, /* CHK.L */ + 268, /* CHK.L */ + 276, /* CHK.L */ + 284, /* CHK.L */ + 292, /* CHK.L */ + 300, /* CHK.L */ + 304, /* MUL .L */ + 305, /* DIV .L */ + 308, /* CHK.L */ + 316, /* CHK.L */ + 931, /* BFTST */ + 935, /* BFEXTU */ + 939, /* BFCHG */ + 943, /* BFEXTS */ + 947, /* BFCLR */ + 951, /* BFFFO */ + 955, /* BFSET */ + 959, /* BFINS */ + 1027, /* RTM */ + 1028, /* UNPK */ + 1032, /* PACK */ + 1040, /* CAS2 */ + 1041, /* CAS2 */ + 1042, /* CAS2 */ + 1045, /* TRAPcc */ + 1049, /* BKPT */ + 1051, /* EXTB.L */ + 0 + }; + +short fpu68881_disabled [] = + { + 968, /* General fpu opcode */ + 969, /* FScc */ + 970, /* FBcc */ + 971, /* FBcc */ + 972, /* FSAVE */ + 973, /* FRESTORE */ + 1047, /* FDBcc */ + 1048, /* FTRAPcc */ + 0 + }; + +short cpu68030_disabled [] = + { + 960, /* MMU instructions */ + 0 + }; + +short cpu68040_disabled [] = + { + 976, /* CPUSH, CINV */ + 977, /* CPUSH, CINV */ + 978, /* CPUSH, CINV */ + 979, /* CPUSH, CINV */ + 980, /* PFLUSH */ + 981, /* PTEST */ + 984, /* MOVE16 */ + 0 + }; + +short cpu68060_disabled [] = + { + 982, /* PLPAW */ + 983, /* PLPAR */ + 0 + }; + +short cpuCF_disabled [] = + { + 452, /* MVS.B */ + 453, /* MVS.W */ + 454, /* MVZ.B */ + 455, /* MVZ.W */ + 460, /* MVS.B */ + 461, /* MVS.W */ + 462, /* MVZ.B */ + 463, /* MVZ.W */ + 468, /* MVS.B */ + 469, /* MVS.W */ + 470, /* MVZ.B */ + 471, /* MVZ.W */ + 476, /* MVS.B */ + 477, /* MVS.W */ + 478, /* MVZ.B */ + 479, /* MVZ.W */ + 484, /* MVS.B */ + 485, /* MVS.W */ + 486, /* MVZ.B */ + 487, /* MVZ.W */ + 492, /* MVS.B */ + 493, /* MVS.W */ + 494, /* MVZ.B */ + 495, /* MVZ.W */ + 500, /* MVS.B */ + 501, /* MVS.W */ + 502, /* MVZ.B */ + 503, /* MVZ.W */ + 508, /* MVS.B */ + 509, /* MVS.W */ + 510, /* MVZ.B */ + 511, /* MVZ.W */ + 645, /* MOV3Q */ + 653, /* MOV3Q */ + 661, /* MOV3Q */ + 669, /* MOV3Q */ + 677, /* MOV3Q */ + 685, /* MOV3Q */ + 693, /* MOV3Q */ + 701, /* MOV3Q */ + 1056, /* BITREV */ + 1057, /* BYTEREV */ + 1058, /* FF1 */ + 1059, /* SATS */ + 0 + }; diff --git a/cputest/adis/opcode_handler_cpu.c b/cputest/adis/opcode_handler_cpu.c new file mode 100644 index 00000000..4afbc9f2 --- /dev/null +++ b/cputest/adis/opcode_handler_cpu.c @@ -0,0 +1,1220 @@ +/* + * Change history + * $Log: opcode_handler_cpu.c,v $ + * + * Revision 3.1 09/10/15 Matt Hey + * Fixed mulsl.l, mulul.l, bf width of 32 + * + * Revision 3.0 93/09/24 17:54:12 Martin_Apel + * New feature: Added extra 68040 FPU opcodes + * + * Revision 2.2 93/07/18 22:56:17 Martin_Apel + * *** empty log message *** + * + * Revision 2.1 93/07/08 20:48:55 Martin_Apel + * Minor mod.: Disabled internal error message in non-debugging version + * + * Revision 2.0 93/07/01 11:54:21 Martin_Apel + * *** empty log message *** + * + * Revision 1.14 93/07/01 11:41:49 Martin_Apel + * Minor mod.: Now checks for zero upper byte on using CCR + * + * Revision 1.13 93/06/16 20:28:56 Martin_Apel + * Minor mod.: Removed #ifdef FPU_VERSION and #ifdef MACHINE68020 + * Minor mod.: Added variables for 68030 / 040 support + * + * Revision 1.12 93/06/06 13:47:17 Martin_Apel + * Minor mod.: Replaced first_pass and read_symbols by pass1, pass2, pass3 + * + * Revision 1.11 93/06/03 20:28:42 Martin_Apel + * Minor mod.: Additional linefeed generation for end instructions has been + * moved to format_line + * + * Revision 1.10 93/05/27 20:47:51 Martin_Apel + * Bug fix: Register list was misinterpreted for MOVEM / FMOVEM + * instructions. + * + */ + +#include "defs.h" + +/* static char rcsid [] = "$Id: opcode_handler_cpu.c,v 3.1 09/10/15 Martin_Apel Exp $"; */ + +/**********************************************************************/ + +uint EA_to_Rn (struct opcode_entry *op) + +/* 2 op instruction where src is an EA and dest is a register (op->param) */ +{ +if (pass3) + str_cpy (dest, reg_names [op->param]); +return (decode_ea (src, MODE_NUM (*code), REG_NUM (*code), op->access, 1) + 1); +} + +/**********************************************************************/ + +uint Rn_to_EA (struct opcode_entry *op) + +/* 2 op instruction where src is a register (op->param) and dest is an EA */ +{ +if (pass3) + str_cpy (src, reg_names [op->param]); +return (decode_ea (dest, MODE_NUM (*code), REG_NUM (*code), op->access, 1) + 1); +} + +/**********************************************************************/ + +uint op1 (struct opcode_entry *op) + +/* handler for 1 op instructions */ +{ +return (decode_ea (src, MODE_NUM(*code), REG_NUM(*code), op->access, 1) + 1); +} + +/**********************************************************************/ + +uint op1_end (struct opcode_entry *op) + +/* handler for a single operand instruction ending an instruction sequence + i.e. jmp rtm */ +{ +instr_end = TRUE; +return (decode_ea (src, MODE_NUM(*code), REG_NUM(*code), op->access, 1) + 1); +} + +/**********************************************************************/ + +uint quick (struct opcode_entry *op) + +/* handler for addq and subq */ +{ +if (pass3) + { + char *to; + + to = src; + *to++ = '#'; + *to++ = (UBYTE)(op->param) + '0'; + *to = 0; + } +return (decode_ea (dest, MODE_NUM (*code), REG_NUM (*code), op->access, 1) + 1); +} + +/**********************************************************************/ + +uint moveq (struct opcode_entry *op) + +{ +if (pass3) + { + char *to; + to = src; + *to++ = '#'; + format_x (to, (BYTE)(*code)); + str_cpy (dest, reg_names [op->param]); + } +return (1); +} + +/**********************************************************************/ + +uint move (struct opcode_entry *op) + +{ +uint used; + +used = decode_ea (src, MODE_NUM (*code), REG_NUM (*code), op->access, 1); +used += decode_ea (dest,((*code >> 6) & 0x7), ((*code >> 9) & 0x7), + op->access, used + 1); +return (used + 1); +} + +/**********************************************************************/ + +uint movem (struct opcode_entry *op) + +{ +char *reg_list; +uint used; + +if (op->param == REG_TO_MEM) + { + /* Transfer registers to memory */ + reg_list = src; + used = decode_ea (dest, MODE_NUM (*code), REG_NUM (*code), ACC_DATA, 2); + } +else + { + reg_list = dest; + used = decode_ea (src, MODE_NUM (*code), REG_NUM (*code), ACC_DATA, 2); + } + +if (pass3) + { + format_reg_list (reg_list, *(code + 1), (MODE_NUM (*code) != 4), 0); + if (*reg_list == 0) + { + /* some compilers generate empty reg lists for movem instructions */ + *reg_list++ = '#'; + *reg_list++ = '0'; + *reg_list = 0; + } + } +return (used + 2); +} + +/**********************************************************************/ + +uint imm_b (struct opcode_entry *op) + +/* handler for ori.b andi.b eori.b subi.b addi.b cmpi.b callm */ +{ +ULONG instr = *(ULONG*)code; + +if ((instr & 0xfc0000ff) == 0) /* if ori.b #0,ea or andi.b #0,ea */ + { + /* ori.b #0,ea and andi.b #0,ea are probably not code */ + instr_bad = TRUE; + return (1); + } +instr &= 0x0000ff00; +if (!((instr == 0) || (instr == 0x0000ff00))) /* GCC immediate may be $ffxx */ + { + /* probably not code if upper byte of immediate has trash */ + instr_bad = TRUE; + return (1); + } + +if (pass3) + { + char *to; + to = src; + *to++ = '#'; + format_ux (to, (*(code + 1) & 0xff)); + } +return (decode_ea (dest, MODE_NUM(*code), REG_NUM(*code), op->access, 2) + 2); +} + +/**********************************************************************/ + +uint imm_w (struct opcode_entry *op) + +/* handler for ori.w andi.w eori.w subi.w addi.w cmpi.w */ +{ +if ((*((ULONG*)code) & 0xfc00ffff) == 0) + { + /* ori.w #0,ea and andi.w #0,ea are probably not code */ + instr_bad = TRUE; + return (1); + } + +if (pass3) + { + char *to; + to = src; + *to++ = '#'; + format_ux (to, *(code + 1)); + } +return (decode_ea (dest, MODE_NUM(*code), REG_NUM(*code), op->access, 2) + 2); +} + +/**********************************************************************/ + +uint imm_l (struct opcode_entry *op) + +/* handler for ori.l andi.l eori.l subi.l addi.l cmpi.l */ +{ +register ULONG instr_ext = *(ULONG*)(code + 1); + +if ((instr_ext == 0) && (*(code) & 0xfc00) == 0) + { + /* ori.l #0,ea and andi.l #0,ea are probably not code */ + instr_bad = TRUE; + return (1); + } + +if (pass2 && FLAGS_RELOC (current_ref + 2)) + { + enter_ref (instr_ext, NULL, ACC_UNKNOWN); + + /* Needed for jump tables? + if (EVEN (instr_ext) && instr_ext >= first_ref && instr_ext < last_ref) + last_code_reference = instr_ext; + */ + } +else if (pass3) + { + char *to; + + to = src; + *to++ = '#'; + if (FLAGS_RELOC (current_ref + 2)) + { + /* This reference is relocated and thus needs a label */ + *to++ = '('; + to = gen_label_ref (to, instr_ext); + *to++ = ')'; + *to = 0; + } + else + format_ulx (to, instr_ext); + } +return (decode_ea (dest, MODE_NUM(*code), REG_NUM(*code), op->access, 3) + 3); +} + +/**********************************************************************/ + +uint bit_reg (struct opcode_entry *op) + +{ +UWORD code_w = *code; + +if (pass3) + str_cpy (src, reg_names [op->param]); + +if (MODE_NUM (code_w) == 0) /* data register */ + { + if (pass3) + str_cpy (dest, reg_names [REG_NUM (code_w)]); + return (1); + } +else + return (decode_ea (dest, MODE_NUM (code_w), REG_NUM (code_w), ACC_BYTE, 1) + 1); +} + +/**********************************************************************/ + +uint bit_imm (struct opcode_entry *op) + +{ +UWORD code_w = *code; +UWORD data_w = *(code + 1); + +if ((data_w & 0xff00) != 0) + { + /* only bit #0-255 are valid */ + instr_bad = TRUE; + return (1); + } + +if (pass3) + { + char *to; + to = src; + *to++ = '#'; + format_ux (to, data_w); + } + +if (MODE_NUM (code_w) == 0) /* data register */ + { + if (pass3) + str_cpy (dest, reg_names [REG_NUM (code_w)]); + return (2); + } +else + return (decode_ea (dest, MODE_NUM (code_w), REG_NUM(code_w), ACC_BYTE, 2) + 2); +} + +/**********************************************************************/ + +uint srccr (struct opcode_entry *op) + +/* ANDI, ORI, EORI to CCR or SR */ +{ +UWORD size = (*code & 0x00C0) >> 6; /* size: byte=0 word=1 long=2 */ +/* Only allow word size SR or byte size CCR instructions. */ +if (size == 0 && (*(code + 1) & 0xff00)) + return (TRANSFER); +if (pass3) + { + str_cpy (opcode, opcode_table [*code >> 6].mnemonic); + immed (src, (ULONG)(*(code + 1))); + str_cpy (dest, special_regs [!size]); + } +return (2); +} + +/**********************************************************************/ + +uint special (struct opcode_entry *op) + +{ +/* move usp, 10dxxx + trap, 00xxxx + unlk, 011xxx + link.w 010xxx + + reset, 110000 + nop, 110001 + stop, 110010 + rte, 110011 + rtd, 110100 + rts, 110101 + trapv 110110 + rtr, 110111 + + movec, 11101d +*/ + +char *ptr = NULL; +uint used = 1; + +if ((*code & 0x38) == 0x30) + { + switch (*code & 0xf) + { + case 0: ptr = "reset"; + break; + case 1: ptr = "nop"; + break; + case 2: ptr = "stop"; + if (pass3) + immed (src, (ULONG)*(code + 1)); + used = 2; + break; + case 3: ptr = "rte"; + instr_end = TRUE; + break; + case 4: if (!cpu68020) + return (TRANSFER); + ptr = "rtd"; + instr_end = TRUE; + if (pass3) + { + src [0] = '#'; + format_ux (src + 1, (UWORD)*(code + 1)); + } + used = 2; + break; + case 5: ptr = "rts"; + instr_end = TRUE; + break; + case 6: ptr = "trapv"; + break; + case 7: ptr = "rtr"; + instr_end = TRUE; + break; + } + if (pass3) + str_cpy (opcode, ptr); + return (used); + } +else if ((*code & 0x3e) == 0x3a) /* MOVEC */ + { + short reg_offset; + + if (!cpu68020) + return (TRANSFER); + switch (*(code + 1) & 0xfff) + { + case 0x000: ptr = special_regs [SFC]; + break; + case 0x001: ptr = special_regs [DFC]; + break; + case 0x002: ptr = special_regs [CACR]; + break; + case 0x003: if (cpu68040) + ptr = special_regs [TC]; + else + return (TRANSFER); + break; + case 0x004: if (cpu68040) + ptr = special_regs [ITT0]; + else + return (TRANSFER); + break; + case 0x005: if (cpu68040) + ptr = special_regs [ITT1]; + else + return (TRANSFER); + break; + case 0x006: if (cpu68040) + ptr = special_regs [DTT0]; + else + return (TRANSFER); + break; + case 0x007: if (cpu68040) + ptr = special_regs [DTT1]; + else + return (TRANSFER); + break; + case 0x800: ptr = special_regs [USP]; + break; + case 0x801: ptr = special_regs [VBR]; + break; + case 0x802: ptr = special_regs [CAAR]; + break; + case 0x803: ptr = special_regs [MSP]; + break; + case 0x804: ptr = special_regs [ISP]; + break; + case 0x805: if (cpu68040) + ptr = special_regs [MMUSR]; + else + return (TRANSFER); + break; + case 0x806: if (cpu68040) + ptr = special_regs [URP]; + else + return (TRANSFER); + break; + case 0x807: if (cpu68040) + ptr = special_regs [SRP]; + else + return (TRANSFER); + break; + default : return (TRANSFER); + } + + reg_offset = (*(code + 1) & 0x8000) ? 8 : 0; + if (pass3) + { + str_cpy (opcode, "movec.l"); + if (*code & 0x1) + { + /* from general register to control register */ + str_cpy (dest, ptr); + str_cpy (src, reg_names [((*(code + 1) >> 12) & 0x7) + reg_offset]); + } + else + { + str_cpy (src, ptr); + str_cpy (dest, reg_names [((*(code + 1) >> 12) & 0x7) + reg_offset]); + } + } + return (2); + } +else if ((*code & 0x30) == 0) + { + /* TRAP */ + if (pass3) + { + str_cpy (opcode, "trap"); + src [0] = '#'; + format_ux (src + 1, (UWORD)(*code & 0xf)); + } + return (1); + } +else if ((*code & 0x38) == 0x10) + { + /* LINK */ + if (pass3) + { + str_cpy (opcode, "link"); + str_cpy (src, reg_names [(*code & 0x7) + 8]); + dest [0] = '#'; + format_x (dest + 1, (WORD)*(code + 1)); + } + return (2); + } +else if ((*code & 0x38) == 0x18) + { + /* UNLK */ + if (pass3) + { + str_cpy (opcode, "unlk"); + str_cpy (src, reg_names [(*code & 0x7) + 8]); + } + return (1); + } +else if ((*code & 0x38) == 0x20) + { + if (pass3) + { + str_cpy (opcode, "move.l"); + str_cpy (dest, special_regs [USP]); + str_cpy (src, reg_names [(*code & 0x7) + 8]); + } + return (1); + } +else if ((*code & 0x38) == 0x28) + { + if (pass3) + { + str_cpy (opcode, "move"); + str_cpy (src, special_regs [USP]); + str_cpy (dest, reg_names [(*code & 0x7) + 8]); + } + return (1); + } +return (TRANSFER); +} + +/**********************************************************************/ + +uint illegal (struct opcode_entry *op) + +/* The official illegal instruction */ +{ +return (1); +} + +/**********************************************************************/ + +uint invalid (struct opcode_entry *op) + +/* unimplemented instruction */ +{ +src [0] = 0; +dest [0] = 0; +instr_bad = TRUE; +return (1); +} + +/**********************************************************************/ + +uint invalid2 (struct opcode_sub_entry *op) + +/* unimplemented instruction in the mmu & fpu sub tables */ +{ +src [0] = 0; +dest [0] = 0; +instr_bad = TRUE; +return (1); +} + +/**********************************************************************/ + +uint branch (struct opcode_entry *op) + +{ +uint used; +ULONG ref; +register LONG offset = (BYTE)(*code & 0xff); + +if (offset == 0) + { + /* word displacement */ + offset = (WORD)*(code + 1); + used = 2; + } +else if (offset == -1) + { + /* long displacement */ + if (!cpu68020) + return (TRANSFER); + offset = *(LONG*)(code + 1); + used = 3; + } +else + { + /* byte displacement */ + used = 1; + } + +ref = offset + current_ref + 2; +if (ODD (offset) || ref < first_ref || ref >= last_ref) + return (TRANSFER); + +if (pass3) + { + gen_label_ref (src, ref); + if (branch_sizes) + { + if (used == 1) + str_cat (opcode, ".b"); + else if (used == 2) + str_cat (opcode, ".w"); + else + str_cat (opcode, ".l"); + } + } +else + { + enter_ref (ref, NULL, ACC_CODE); + if ((*code & 0xff00) == 0x6000) /* bra */ + instr_end = TRUE; /* NOT on pass3 as it looks better without blank line */ + } +return (used); +} + +/**********************************************************************/ + +uint dbranch (struct opcode_entry *op) + +{ +ULONG ref; + +if (*(code + 1) & 0x1) /* branch to an odd address */ + return (TRANSFER); + +if (pass3) + str_cpy (src, reg_names [*code & 7]); +ref = current_ref + 2 + (short)(*(code + 1)); +if (ref < first_ref || ref > last_ref) + return (TRANSFER); +if (pass3) + gen_label_ref (dest, ref); +else + enter_ref (ref, NULL, ACC_CODE); + +return (2); +} + +/**********************************************************************/ + +uint shiftreg (struct opcode_entry *op) + +{ +if (pass3) + { + opcode [1] = 's'; + opcode [2] = 0; + switch ((*code >> 3) & 0x3) + { + case 0: /* Arithmetic shift */ + opcode [0] = 'a'; + break; + case 1: /* Logical shift */ + opcode [0] = 'l'; + break; + case 2: /* Rotate with extend */ + str_cpy (opcode, "rox"); + break; + case 3: /* Rotate */ + opcode [0] = 'r'; + opcode [1] = 'o'; + break; + } + str_cat (opcode, op->mnemonic); + + if (*code & 0x20) + { + /* shift count is in register */ + str_cpy (src, reg_names [op->param & 0x7]); + /* This is because param gives a shift count of 8, if this bitfield is 0 */ + } + else + { + /* shift count specified as immediate */ + src [0] = '#'; + format_ux (src + 1, (UWORD)op->param); + } + + str_cpy (dest, reg_names [REG_NUM (*code)]); + } +return (1); +} + +/**********************************************************************/ + +uint op2_bcdx (struct opcode_entry *op) + +/* For opcodes such as ADDX, SUBX, ABCD, SBCD, PACK, UNPK with only + -(Ax) and Dn addressing allowed */ +{ +char *tmp; + +if (pass3) + { + if (*code & 0x8) + { + /* -(Ax) addressing */ + pre_dec (src, (ushort)(REG_NUM (*code) + 8)); + pre_dec (dest, (ushort)(((*code >> 9) & 0x7) + 8)); + } + else + { + /* Dn addressing */ + str_cpy (src, reg_names [REG_NUM (*code)]); + str_cpy (dest, reg_names [((*code >> 9) & 0x7)]); + } + } + +if (op->param == NO_ADJ) + return (1); +else + { + if (pass3) + { + tmp = dest + strlen (dest); + *tmp++ = ','; + immed (tmp, (ULONG)*(code + 1)); + } + return (2); + } +} + +/**********************************************************************/ + +uint muldivl (struct opcode_entry *op) + +{ +UWORD instr1w = *code; +UWORD instr2w = *(code + 1); +UWORD access = ACC_LONG; + +if ((instr2w & 0x800) != 0) + access |= ACC_SIGNED; + +if (pass3) + { + char *tmp_o; + char *tmp_d; + register UWORD dr, dq; + + tmp_o = opcode + 3; + + if (access & ACC_SIGNED) + *tmp_o++ = 's'; + else + *tmp_o++ = 'u'; + + dr = instr2w & 0x7; + dq = (instr2w >> 12) & 0x7; + + tmp_d = dest; + + if (instr2w & 0x400) + { + /* 64-bit operation, size = 1 */ + tmp_d = str_cpy (tmp_d, reg_names [dr]); + *tmp_d++ = ':'; + } + else if ((instr1w & 0x40) && (dr != dq)) + { + /* divl */ + *tmp_o++ = 'l'; + tmp_d = str_cpy (tmp_d, reg_names [dr]); + *tmp_d++ = ':'; + } + str_cpy (tmp_d, reg_names [dq]); + *tmp_o++ = '.'; + *tmp_o++ = 'l'; + *tmp_o = 0; + } +return (decode_ea (src, MODE_NUM (instr1w), REG_NUM (instr1w), access, 2) + 2); +} + +/**********************************************************************/ + +uint bitfield (struct opcode_entry *op) + +{ +uint used; +UWORD offset, width; +register char *ptr_ea = NULL, *ptr_dn = NULL; + +offset = (*(code + 1) >> 6) & 0x1f; +width = *(code + 1) & 0x1f; + +switch (op->param) + { + case SINGLEOP: ptr_ea = src; + break; + case DATADEST: ptr_ea = src; + ptr_dn = dest; + break; + case DATASRC : ptr_ea = dest; + ptr_dn = src; + break; + } + +used = decode_ea (ptr_ea, MODE_NUM (*code), REG_NUM (*code), ACC_DATA, 2); + +if (pass3) + { + ptr_ea = str_cat (ptr_ea, "{"); + if (op->param != SINGLEOP) + str_cpy (ptr_dn, reg_names [(*(code + 1) >> 12) & 0x7]); + } + +if (*(code + 1) & 0x800) + { + /* Offset specified in register */ + if (offset > 7) + return (TRANSFER); + if (pass3) + ptr_ea = str_cpy (ptr_ea, reg_names [offset]); + } +else if (pass3) + { + /* Offset specified as immediate */ + ptr_ea = format_ux (ptr_ea, offset); + } + +if (pass3) + *ptr_ea++ = ':'; + +if (*(code + 1) & 0x20) + { + /* Width specified in register */ + if (width > 7) + return (TRANSFER); + if (pass3) + ptr_ea = str_cpy (ptr_ea, reg_names [width]); + } +else if (pass3) + { + /* Width specified as immediate */ + if (!width) + width = 0x20; + ptr_ea = format_ux (ptr_ea, width); + } + +if (pass3) + { + *ptr_ea++ = '}'; + *ptr_ea = 0; + } + +return (2 + used); +} + +/**********************************************************************/ + +uint scc (struct opcode_entry *op) + +{ +if (pass3) + str_cat (opcode, conditions [(*code >> 8) & 0xf]); +return (decode_ea (src, MODE_NUM (*code), REG_NUM (*code), ACC_BYTE, 1) + 1); +} + +/**********************************************************************/ + +uint exg (struct opcode_entry *op) + +{ +UWORD rx = (*code >> REG2_SHIFT) & 0x7; + +if (((*code >> 3) & 0x1f) == 0x8) + { + /* exchange two data registers */ + if (pass3) + { + str_cpy (src, reg_names [rx]); + str_cpy (dest, reg_names [*code & 0x7]); + } + } +else if (((*code >> 3) & 0x1f) == 0x9) + { + /* exchange two address registers */ + if (pass3) + { + str_cpy (src, reg_names [rx + 8]); + str_cpy (dest, reg_names [(*code & 0x7) + 8]); + } + } +else if (((*code >> 3) & 0x1f) == 0x11) + { + /* exchange an address and a data register */ + if (pass3) + { + str_cpy (src, reg_names [rx]); + str_cpy (dest, reg_names [(*code & 0x7) + 8]); + } + } +else + return (TRANSFER); +return (1); +} + +/**********************************************************************/ + +uint trapcc (struct opcode_entry *op) + +{ +if (pass3) + str_cat (opcode, conditions [(*code >> 8) & 0xf]); +if ((*code & 0x7) == 2) + { + if (pass3) + immed (src, (ULONG)*(code + 1)); + return (2); + } +if ((*code & 0x7) == 3) + { + if (pass3) + immed (src, *(ULONG*)(code + 1)); + return (3); + } +return (1); +} + +/**********************************************************************/ + +uint chkcmp2 (struct opcode_entry *op) + +{ +if (pass3) + { + if (*(code + 1) & 0x800) + { + /* CHK2 */ + opcode [1] = 'h'; + opcode [2] = 'k'; + } + else + { + /* CMP2 */ + opcode [1] = 'm'; + opcode [2] = 'p'; + } + if (pass3) + str_cpy (dest, reg_names [*(code + 1) >> 12]); + } +return (decode_ea (src, MODE_NUM (*code), REG_NUM (*code), op->access, 2) + 2); +} + +/**********************************************************************/ + +uint cas (struct opcode_entry *op) + +{ +register char *tmp_s; + +if (pass3) + { + tmp_s = str_cpy (src, reg_names [*(code + 1) & 0x7]); + *tmp_s++ = ','; + str_cpy (tmp_s, reg_names [(*(code + 1) >> 6) & 0x7]); + } +return (decode_ea (dest, MODE_NUM (*code), REG_NUM (*code), op->access, 2) + 2); +} + +/**********************************************************************/ + +uint cas2 (struct opcode_entry *op) + +{ +if (pass3) + { + sprintf (src, "%s:%s,%s:%s", reg_names [*(code + 1) & 0x7], + reg_names [*(code + 2) & 0x7], + reg_names [(*(code + 1) >> 6) & 0x7], + reg_names [(*(code + 2) >> 6) & 0x7]); + + sprintf (dest, "(%s):(%s)", reg_names [*(code + 1) >> 12], + reg_names [*(code + 2) >> 12]); + } +return (3); +} + +/**********************************************************************/ + +uint moves (struct opcode_entry *op) + +{ +char *reg, *ea; + +if (*(code + 1) & 0x800) + { + reg = src; + ea = dest; + } +else + { + reg = dest; + ea = src; + } + +if (pass3) + str_cpy (reg, reg_names [(*(code + 1) >> 12) & 0xf]); +return (decode_ea (ea, MODE_NUM (*code), REG_NUM (*code), op->access, 2) + 2); +} + +/**********************************************************************/ + +uint movesrccr (struct opcode_entry *op) + +{ +char *ea = NULL; + +if (pass3) + { + switch (op->param) + { + case FROM_CCR: str_cpy (src, special_regs [CCR]); + ea = dest; + break; + case TO_CCR : str_cpy (dest, special_regs [CCR]); + ea = src; + break; + case FROM_SR : str_cpy (src, special_regs [SR]); + ea = dest; + break; + case TO_SR : str_cpy (dest, special_regs [SR]); + ea = src; + break; + } + } +return (decode_ea (ea, MODE_NUM (*code), REG_NUM (*code), ACC_WORD, 1) + 1); +} + +/**********************************************************************/ + +uint cmpm (struct opcode_entry *op) + +{ +if (pass3) + { + post_inc (src, (*code & 0xf)); + post_inc (dest, ((*code >> 9) & 0xf)); + } +return (1); +} + +/**********************************************************************/ + +uint movep (struct opcode_entry *op) + +{ +char *dn, *an; + +if (pass3) + { + if (*code & 0x40) + str_cat (opcode, ".l"); + else + str_cat (opcode, ".w"); + } +if (*code & 0x80) + { + /* Transfer to memory */ + an = dest; + dn = src; + } +else + { + /* Transfer from memory */ + an = src; + dn = dest; + } + +if (pass3) + { + str_cpy (dn, reg_names [(*code >> 9) & 0x7]); + disp_an (an, ((*code & 0x7) + 8), *(code + 1)); + } +return (2); +} + +/**********************************************************************/ + +uint bkpt (struct opcode_entry *op) + +{ +if (pass3) + { + src [0] = '#'; + format_ux (src + 1, (UWORD)(*code & 0x7)); + } +return (1); +} + +/**********************************************************************/ + +uint link_l (struct opcode_entry *op) + +{ +if (pass3) + { + dest [0] = '#'; + format_ulx (dest + 1, *(ULONG*)(code + 1)); + str_cpy (src, reg_names [REG_NUM (*code) + 8]); + } +return (3); +} + +/**********************************************************************/ + +uint move16 (struct opcode_entry *op) + +{ +char *tmp; + +if ((*code & 0x20) && ((*(code + 1) & 0x8fff) == 0x8000)) + { /* post increment mode for src and dest */ + if (pass3) + { + post_inc (src, (*code & 0x7) + 8); + post_inc (dest, ((*(code + 1) >> 12) & 0x7) + 8); + } + return (2); + } +else if ((*code & 0x20) == 0) + { + if (pass3) + { + if (*code & 0x8) + { + tmp = dest; + decode_ea (src, 7, 1, ACC_LONG, 1); + } + else + { + tmp = src; + decode_ea (dest, 7, 1, ACC_LONG, 1); + } + if (*code & 0x10) + indirect (tmp, (*code & 0x7) + 8); + else + post_inc (tmp, (*code & 0x7) + 8); + } + return (3); + } +return (TRANSFER); +} + +/**********************************************************************/ + +uint cache (struct opcode_entry *op) + +{ +char *tmp_o; + +if (pass3) + { + if (*code & 0x20) + tmp_o = str_cpy (opcode, "cpush"); + else + tmp_o = str_cpy (opcode, "cinv"); + switch ((*code >> 3) & 0x3) + { + case 1: *tmp_o++ = 'l'; break; + case 2: *tmp_o++ = 'p'; break; + case 3: *tmp_o++ = 'a'; break; + } + *tmp_o = 0; + + switch (op->param) /* which cache to modify */ + { + case 0: str_cpy (src, "nc"); break; + case 1: str_cpy (src, "dc"); break; + case 2: str_cpy (src, "ic"); break; + case 3: str_cpy (src, "bc"); break; + } + + if (((*code >> 3) & 0x3) != 0x3) /* not all --> page or line */ + indirect (dest, (REG_NUM (*code) + 8)); + } +return (1); +} + +/********************************************************************** + ColdFire handlers +**********************************************************************/ + +uint mov3q (struct opcode_entry *op) + +/* handler for ColdFire mov3q */ +{ +if (pass3) + { + char *to; + to = src; + *to++ = '#'; + UBYTE data = (UBYTE)op->param; + if (data) + *to++ = data + '0'; + else + { + *to++ = '-'; + *to++ = '1'; + } + *to = 0; + } +return (decode_ea (dest, MODE_NUM(*code), REG_NUM(*code), ACC_LONG, 1) + 1); +} diff --git a/cputest/adis/opcode_handler_fpu.c b/cputest/adis/opcode_handler_fpu.c new file mode 100644 index 00000000..3a783086 --- /dev/null +++ b/cputest/adis/opcode_handler_fpu.c @@ -0,0 +1,402 @@ +/* + * Change history: + * $Log: opcode_handler_fpu.c,v $ + * Revision 3.0 93/09/24 17:54:15 Martin_Apel + * New feature: Added extra 68040 FPU opcodes + * + * Revision 2.1 93/07/18 22:56:24 Martin_Apel + * *** empty log message *** + * + * Revision 2.0 93/07/01 11:54:27 Martin_Apel + * *** empty log message *** + * + * Revision 1.7 93/06/16 20:29:03 Martin_Apel + * Minor mod.: Removed #ifdef FPU_VERSION and #ifdef MACHINE68020 + * Minor mod.: Added variables for 68030 / 040 support + * + * Revision 1.6 93/06/06 13:47:37 Martin_Apel + * Minor mod.: Replaced first_pass and read_symbols by pass1, pass2, pass3 + * + * Revision 1.5 93/05/27 20:48:41 Martin_Apel + * Bug fix: Register list was misinterpreted for MOVEM / FMOVEM + * instructions. + * + */ + +#include "defs.h" + +/* static char rcsid [] = "$Id: opcode_handler_fpu.c,v 3.0 93/09/24 17:54:15 Martin_Apel Exp $"; */ + +/**********************************************************************/ + +uint fpu (struct opcode_entry *op) + +{ +uint used; +char *reg_list, + *ea; +register char *tmp = NULL; +uint num_regs; +register UWORD instr_word1; +register UWORD instr_word2; +register UWORD mode; + +instr_word1 = *code; +instr_word2 = *(code + 1); +mode = MODE_NUM (instr_word1); +if ((instr_word2 & 0xfc00) == 0x5c00) + { + /* fmovecr */ + if (pass3) + { + str_cpy (opcode, "fmovecr.x"); + immed (src, (ULONG)(instr_word2 & 0x7f)); + str_cpy (dest, reg_names [17 + ((instr_word2 >> 7) & 0x7)]); + } + return (2); + } +else + { + switch (instr_word2 >> 13) + { + case 0: + case 2: /* Use the fpu_opcode_table */ + if ((instr_word2 & 0x0040) && !cpu68040) + return (TRANSFER); + struct opcode_sub_entry *subop; + subop = &(fpu_opcode_table [instr_word2 & 0x7f]); + return ((*subop->handler) (subop)); + + case 3: /* fmove from FPx */ + if (pass3) + { + tmp = str_cpy (opcode, "fmove"); + str_cpy (tmp, xfer_size [(instr_word2 >> 10) & 0x7]); + str_cpy (src, reg_names [17 + ((instr_word2 >> 7) & 0x7)]); + } + used = decode_ea (dest, mode, REG_NUM (instr_word1), + sizes [(instr_word2 >> 10) & 0x7], 2); + if ((instr_word2 & 0x1c00) == 0x0c00) + { + /* Packed decimal real with static k-factor */ + if (pass3) + { + tmp = dest + strlen (dest); + *tmp++ = '{'; + tmp = immed (tmp, (ULONG)(instr_word2 & 0x7f)); + *tmp++ = '}'; + *tmp = 0; + /* Same as: + sprintf (dest + strlen (dest), "{#$%x}", + instr_word2 & 0x7f); + */ + } + } + else if ((instr_word2 & 0x1c00) == 0x1c00) + { + /* Packed decimal real with dynamic k-factor */ + if (pass3) + { + tmp = dest + strlen (dest); + *tmp++ = '{'; + tmp = str_cpy (tmp, reg_names [(instr_word2 >> 4) & 0x7]); + *tmp++ = '}'; + *tmp = 0; + /* Same as: + sprintf (dest + strlen (dest), "{%s}", + reg_names [(instr_word2 >> 4) & 0x7]); + */ + } + } + return (2 + used); + + case 4: + case 5: /* fmove.l and fmovem.l control registers */ + num_regs = 0; + if (pass3) + tmp = str_cpy (opcode, "fmove"); + if (instr_word2 & 0x2000) + { + ea = dest; + reg_list = src; + } + else + { + ea = src; + reg_list = dest; + } + used = decode_ea (ea, mode, REG_NUM (instr_word1), ACC_LONG, 2); + if (pass3) + { + if (instr_word2 & 0x1000) + { + reg_list = str_cpy (reg_list, "fpcr"); + num_regs++; + } + if (instr_word2 & 0x0800) + { + if (num_regs != 0) + *reg_list++ = '/'; + reg_list = str_cpy (reg_list, "fpsr"); + num_regs++; + } + if (instr_word2 & 0x0400) + { + if (num_regs != 0) + *reg_list++ = '/'; + str_cpy (reg_list, "fpiar"); + num_regs++; + } + if (num_regs > 1) + *tmp++ = 'm'; /* for fmovem.l */ + *tmp++ = '.'; + *tmp++ = 'l'; + *tmp = 0; + } + return (2 + used); + + case 6: + case 7: /* fmovem.x */ + if (mode < 2 || (instr_word1 & 0x3f) == 0x3c) /* dn, an || immediate */ + return (TRANSFER); + if (instr_word2 & 0x2000) + { + /* registers to memory */ + if (mode == 3 || (instr_word1 & 0x3f) >= 0x3a) /* (an)+ || pc modes */ + return (TRANSFER); + reg_list = src; + ea = dest; + } + else + { + /* memory to registers */ + if (mode == 4) /* -(an) */ + return (TRANSFER); + reg_list = dest; + ea = src; + } + + if (pass3) + { + str_cpy (opcode, "fmovem.x"); + if (instr_word2 & 0x0800) + { + /* Dynamic register list in data register */ + str_cpy (reg_list, reg_names [(instr_word2 >> 4) & 0x7]); + } + else + { + /* Test for predecrement mode */ + if (mode == 4) + format_reg_list (reg_list, (instr_word2 & 0xff), + TRUE, 17); + else + format_reg_list (reg_list, (instr_word2 << 8), + FALSE, 17); + } + } + return (decode_ea (ea, mode, REG_NUM (instr_word1), ACC_EXTEND, 2) + 2); + } + } +return (TRANSFER); +} + +/**********************************************************************/ + +uint fbranch (struct opcode_entry *op) + +{ +LONG offset; +ULONG ref; +uint used; + +if (pass3) + str_cat (opcode, fpu_conditions [*code & 0x1f]); +if (!op->param) + { + offset = (WORD)*(code + 1); + used = 2; + } +else + { + offset = *(LONG*)(code + 1); + used = 3; + } + +if (offset == 0 && pass3) + str_cpy (opcode, "fnop"); +else if (offset != 0) + { + ref = current_ref + 2 + offset; + if (ref < first_ref || ref > last_ref) + return (TRANSFER); + if (pass3) + { + gen_label_ref (src, ref); + if (branch_sizes) + { + if (used == 2) + str_cat (opcode, ".w"); + else + str_cat (opcode, ".l"); + } + } + else + enter_ref (ref, NULL, ACC_CODE); + } +return (used); +} + +/**********************************************************************/ + +uint fdbranch (struct opcode_entry *op) + +{ +ULONG ref; + +if ((*(code + 1) & 0xffe0) != 0) + return (TRANSFER); +if ((*code & 0x0038) != 0x8) + return (TRANSFER); +if (pass3) + { + str_cat (opcode, fpu_conditions [*(code + 1)]); + str_cpy (src, reg_names [*code & 0x7]); + } +ref = current_ref + 4 + (WORD)*(code + 2); +if (ref < first_ref || ref > last_ref) + return (TRANSFER); +if (pass3) + gen_label_ref (dest, ref); +else + enter_ref (ref, NULL, ACC_CODE); +return (3); +} + +/**********************************************************************/ + +uint fscc (struct opcode_entry *op) + +{ +if ((*(code + 1) & 0xffe0) != 0) + return (TRANSFER); + +if (pass3) + str_cat (opcode, fpu_conditions [*(code + 1)]); +return (decode_ea (src, MODE_NUM (*code), REG_NUM (*code), ACC_BYTE, 2) + 2); +} + +/**********************************************************************/ + +uint ftrapcc (struct opcode_entry *op) + +{ +if ((*(code + 1) & 0xffe0) != 0) + return (TRANSFER); +if (pass3) + str_cat (opcode, fpu_conditions [*(code + 1)]); +if ((*code & 0x7) == 2) + { + if (pass3) + immed (src, (ULONG)*(code + 2)); + return (3); + } +if ((*code & 0x7) == 3) + { + if (pass3) + immed (src, *(ULONG*)(code + 2)); + return (4); + } + +return (2); +} + +/********************************************************************** + fpu_opcode_table (opcodes_fpu.c) instructions using an opcode_sub_entry +**********************************************************************/ + +uint std_fpu (struct opcode_sub_entry *op) + +{ +char *tmp_op = NULL; + +if (pass3) + { + tmp_op = str_cpy (opcode, op->mnemonic); + str_cpy (dest, reg_names [17 + ((*(code + 1) >> 7) & 0x7)]); + } +if (*(code + 1) & 0x4000) /* R/M - Bit */ + { + if (pass3) + str_cpy (tmp_op, xfer_size [(*(code + 1) >> 10) & 0x7]); + return (decode_ea (src, MODE_NUM (*code), REG_NUM (*code), + sizes [(*(code + 1) >> 10) & 0x7], 2) + 2); + } +else if (pass3) + { + str_cpy (tmp_op, xfer_size [2]); /* ".X" */ + str_cpy (src, reg_names [17 + ((*(code + 1) >> 10) & 0x7)]); + } + +if ((src [2] == dest [2]) && (op->param == SNG_ALL)) /* single operand */ + dest [0] = 0; +return (2); +} + +/**********************************************************************/ + +uint ftst (struct opcode_sub_entry *op) + +/* ftst is unusual because it only allows 1 opcode */ +{ +char *tmp_op = NULL; + +if (pass3) + tmp_op = str_cpy (opcode, op->mnemonic); +if (*(code + 1) & 0x4000) /* R/M - Bit */ + { + if (pass3) + str_cpy (tmp_op, xfer_size [(*(code + 1) >> 10) & 0x7]); + return (decode_ea (src, MODE_NUM (*code), REG_NUM (*code), + sizes [(*(code + 1) >> 10) & 0x7], 2) + 2); + } +else if (pass3) + { + str_cpy (tmp_op, xfer_size [2]); /* ".X" */ + str_cpy (src, reg_names [17 + ((*(code + 1) >> 10) & 0x7)]); + } +return (2); +} + +/**********************************************************************/ + +uint fsincos (struct opcode_sub_entry *op) + +{ +char *tmp_op = NULL; +char *tmp_dest; + +if (pass3) + { + tmp_op = str_cpy (opcode, op->mnemonic); + tmp_dest = str_cpy (dest, reg_names [17 + op->param]); + *tmp_dest++ = ':'; + str_cpy (tmp_dest, reg_names [17 + ((*(code + 1) >> 7) & 0x7)]); + } +if (*(code + 1) & 0x4000) /* R/M-Bit */ + { + if (pass3) + str_cpy (tmp_op, xfer_size [(*(code + 1) >> 10) & 0x7]); + return (decode_ea (src, MODE_NUM (*code), REG_NUM (*code), + sizes [(*(code + 1) >> 10) & 0x7], 2) + 2); + } +else + { + if (pass3) + { + str_cpy (tmp_op, xfer_size [2]); /* ".X" */ + str_cpy (src, reg_names [17 + ((*(code + 1) >> 10) & 0x7)]); + } + return (2); + } +} diff --git a/cputest/adis/opcode_handler_mmu.c b/cputest/adis/opcode_handler_mmu.c new file mode 100644 index 00000000..0e3dbb82 --- /dev/null +++ b/cputest/adis/opcode_handler_mmu.c @@ -0,0 +1,228 @@ +/* + * Change history + * $Log: opcode_handler_mmu.c,v $ + * + * Revision 3.1 09/10/15 Matt_Hey + * New feature: Added 68060 plpa60 MMU function + * + * Revision 3.0 93/09/24 17:54:17 Martin_Apel + * New feature: Added extra 68040 FPU opcodes + * + * Revision 2.4 93/07/18 22:56:27 Martin_Apel + * *** empty log message *** + * + * Revision 2.3 93/07/11 21:39:02 Martin_Apel + * Bug fix: Changed PTEST function for 68030 + * + * Revision 2.2 93/07/08 22:29:17 Martin_Apel + * + * Bug fix: Fixed PFLUSH bug. Mode and mask bits were confused + * + * Revision 2.1 93/07/08 20:49:34 Martin_Apel + * Bug fixes: Fixed various bugs regarding 68030 opcodes + * + * Revision 2.0 93/07/01 11:54:31 Martin_Apel + * *** empty log message *** + * + * Revision 1.3 93/07/01 11:42:59 Martin_Apel + * + * Revision 1.2 93/06/19 12:11:49 Martin_Apel + * Major mod.: Added full 68030/040 support + * + * Revision 1.1 93/06/16 20:29:09 Martin_Apel + * Initial revision + * + */ + +#include "defs.h" + +/* static char rcsid [] = "$Id: opcode_handler_mmu.c,v 3.0 93/09/24 17:54:17 Martin_Apel Exp $"; */ + +/**********************************************************************/ + +uint plpa60 (struct opcode_entry *op) + +{ +indirect (src, (REG_NUM (*code) + 8)); +return (1); +} + +/**********************************************************************/ + +uint pflush40 (struct opcode_entry *op) + +{ +if (pass3) + { + switch ((*code >> 3) & 0x3) + { + case 0: str_cat (opcode, "n"); break; + case 1: break; + case 2: str_cat (opcode, "an"); break; + case 3: str_cat (opcode, "a"); break; + } + if ((*code & 0x10) == 0) + indirect (src, (REG_NUM (*code) + 8)); + } +return (1); +} + +/**********************************************************************/ + +uint ptest40 (struct opcode_entry *op) + +{ +if (pass3) + { + if (*code & 0x20) + str_cat (opcode, "r"); + else + str_cat (opcode, "w"); + indirect (src, (REG_NUM (*code) + 8)); + } +return (1); +} + +/**********************************************************************/ + +PRIVATE BOOL eval_fc (char *to) + +{ +if ((*(code + 1) & 0x0018) == 0x0010) + immed (to, (ULONG)(*(code + 1) & 0x7)); +else if ((*(code + 1) & 0x0018) == 0x0008) + str_cpy (to, reg_names [*(code + 1) & 0x7]); +else if ((*(code + 1) & 0x001f) == 0) + str_cpy (to, special_regs [SFC]); +else if ((*(code + 1) & 0x001f) == 0x0001) + str_cpy (to, special_regs [DFC]); +else return (FALSE); +return (TRUE); +} + +/**********************************************************************/ + +uint mmu30 (struct opcode_entry *op) + +{ +/* Test for PTEST instruction */ +if (((*(code + 1) & 0xfc00) == 0x9c00) && ((*code & 0x003f) != 0)) + return ptest30 (op); +else if (!(*(code + 1) & 0x8000)) + { + struct opcode_sub_entry *subop; + subop = &(mmu_opcode_table [*(code + 1) >> 10]); + if (pass3) + str_cpy (opcode, subop->mnemonic); + return ((*subop->handler) (subop)); + } +return (TRANSFER); +} + +/**********************************************************************/ + +uint ptest30 (struct opcode_entry *op) + +{ +if ((*code & 0x003f) == 0) /* Check for illegal mode */ + return (TRANSFER); + +str_cpy (opcode, "ptestwfc"); +if (*(code + 1) & 0x0200) + opcode [5] = 'R'; +if (!eval_fc (dest)) + return (TRANSFER); +if (*(code + 1) & 0x0100) + { + str_cat (dest, ","); + str_cat (dest, reg_names [(*(code + 1) >> 5) & 0x7]); + } +return (2 + decode_ea (dest, MODE_NUM (*code), REG_NUM (*code), ACC_UNKNOWN, 2)); +} + +/********************************************************************** + mmu_opcode_table (opcodes_mmu.c) instructions using an opcode_sub_entry +**********************************************************************/ + +uint pfl_or_ld (struct opcode_sub_entry *op) + +/* Tests for PLOAD instruction first. Otherwise it's a standard + PFLUSH instruction */ +{ +if ((*(code + 1) & 0x00e0) != 0x0000) + return (pflush30 (op)); + +if ((*code & 0x3f) == 0) + return (TRANSFER); + +str_cpy (opcode, "pload"); +if (*(code + 1) & 0x0200) + str_cat (opcode, "r"); +else + str_cat (opcode, "w"); + +if (!eval_fc (src)) + return (TRANSFER); +return (2 + decode_ea (dest, MODE_NUM (*code), REG_NUM (*code), ACC_UNKNOWN, 2)); +} + +/**********************************************************************/ + +uint pflush30 (struct opcode_sub_entry *op) + +{ +switch (op->param) + { + case 1: /* PFLUSHA */ + if (*(code + 1) != 0x2400) + return (TRANSFER); + str_cat (opcode, "a"); + return (2); + case 4: /* PFLUSH FC,MASK */ + /* EA ignored !?! */ + if (!eval_fc (src)) + return (TRANSFER); + immed (dest, (ULONG)((*(code + 1) >> 5) & 0x7)); + return (2); + + case 6: /* PFLUSH FC,MASK,EA */ + if (!eval_fc (src)) + return (TRANSFER); + str_cat (src, ","); + immed (src + strlen (src), (ULONG)((*(code + 1) >> 5) & 0x7)); + return (2 + decode_ea (dest, MODE_NUM (*code), REG_NUM (*code), + ACC_UNKNOWN, 2)); + } +return (TRANSFER); +} + +/**********************************************************************/ + +uint pmove30 (struct opcode_sub_entry *op) + +{ +char *ea, + *reg; + +if ((*code & 0x003f) == 0) + return (TRANSFER); + +if ((*(code + 1) & 0xff) || ((*(code + 1) & 0x0010) && op->param == MMUSR)) + return (TRANSFER); + +if (*(code + 1) & 0x0200) + { + ea = dest; + reg = src; + } +else + { + ea = src; + reg = dest; + } +if ((*(code + 1) & 0x0100)) + str_cat (opcode, "fd"); + +str_cpy (reg, special_regs [op->param]); +return (2 + decode_ea (ea, MODE_NUM (*code), REG_NUM (*code), ACC_LONG, 2)); +} diff --git a/cputest/adis/opcodes_cpu.c b/cputest/adis/opcodes_cpu.c new file mode 100644 index 00000000..12a6cbb4 --- /dev/null +++ b/cputest/adis/opcodes_cpu.c @@ -0,0 +1,1123 @@ +/* + * Change history + * $Log: opcodes.c,v $ + * + * Revision 3.1 09/10/15 Matt_Hey + * New feature: Added 68060 MMU opcodes for plpaw & plpar + * Minor mod.: pea (and lea) now enter_ref() ACC_UNKNOWN instead of ACC_LONG + * as nothing is known about data length or type at that offset + * + * Revision 3.0 93/09/24 17:54:19 Martin_Apel + * New feature: Added extra 68040 FPU opcodes + * + * Revision 2.2 93/07/18 22:56:30 Martin_Apel + * *** empty log message *** + * + * Revision 2.1 93/07/08 20:49:58 Martin_Apel + * Bug fix: Enabled addressing mode 0 for mmu30 instruction + * + * Revision 2.0 93/07/01 11:54:33 Martin_Apel + * *** empty log message *** + * + * Revision 1.13 93/07/01 11:43:07 Martin_Apel + * Bug fix: TST.x Ax for 68020 enabled (Error in 68020 manual) + * + * Revision 1.12 93/06/19 12:11:54 Martin_Apel + * Major mod.: Added full 68030/040 support + * + * Revision 1.11 93/06/16 20:29:10 Martin_Apel + * Minor mod.: Removed #ifdef FPU_VERSION and #ifdef MACHINE68020 + * Minor mod.: Added variables for 68030 / 040 support + * + * Revision 1.10 93/06/03 20:29:25 Martin_Apel + * + * + */ + +/* The opcode table is an opcode_entry array (defined in defs.h) that is + indexed by the first 10 bits of each instruction encoding. The handler + of that index is then called. See disasm_instr () in disasm_code.c for use. */ + +#include "defs.h" + +/* static char rcsid [] = "$Id: opcodes.c,v 3.0 93/09/24 17:54:19 Martin_Apel Exp $"; */ + +/* If the opcode_table is 16 byte aligned, then only one cache line is needed + per entry instead of 2. Unfortunatly, __attribute__((aligned(16)) doesn't + seem to work with GCC 3.4.0. The Amiga hunk loader can only guarentee 4 byte + alignment (8 with TLSFMem?). Memory could be dynamically allocated, manually + aligned, and copied but that needs more memory and effort. */ + +struct opcode_entry opcode_table [] = +{ +/* *handler , modes, submodes, chain, *mnemonic , param, access */ + +{ imm_b , 0xfd, 0x03, 1026, "ori.b" , 0, ACC_BYTE }, /* 0000 000 000 */ +{ imm_w , 0xfd, 0x03, 1026, "ori.w" , 0, ACC_WORD }, /* 0000 000 001 */ +{ imm_l , 0xfd, 0x03, 1024, "ori.l" , 0, ACC_LONG }, /* 0000 000 010 */ +{ chkcmp2 , 0xe4, 0x0f, 1056, "c 2.b" , 0, ACC_BYTE }, /* 0000 000 011 */ +{ bit_reg , 0xfd, 0x1f, 1037, "btst" , 0, 0 }, /* 0000 000 100 */ +{ bit_reg , 0xfd, 0x03, 1037, "bchg" , 0, 0 }, /* 0000 000 101 */ +{ bit_reg , 0xfd, 0x03, 1037, "bclr" , 0, 0 }, /* 0000 000 110 */ +{ bit_reg , 0xfd, 0x03, 1037, "bset" , 0, 0 }, /* 0000 000 111 */ +{ imm_b , 0xfd, 0x03, 1026, "andi.b" , 0, ACC_BYTE }, /* 0000 001 000 */ +{ imm_w , 0xfd, 0x03, 1026, "andi.w" , 0, ACC_WORD }, /* 0000 001 001 */ +{ imm_l , 0xfd, 0x03, 1024, "andi.l" , 0, ACC_LONG }, /* 0000 001 010 */ +{ chkcmp2 , 0xe4, 0x0f, 1057, "c 2.w" , 0, ACC_WORD }, /* 0000 001 011 */ +{ bit_reg , 0xfd, 0x1f, 1037, "btst" , 1, 0 }, /* 0000 001 100 */ +{ bit_reg , 0xfd, 0x03, 1037, "bchg" , 1, 0 }, /* 0000 001 101 */ +{ bit_reg , 0xfd, 0x03, 1037, "bclr" , 1, 0 }, /* 0000 001 110 */ +{ bit_reg , 0xfd, 0x03, 1037, "bset" , 1, 0 }, /* 0000 001 111 */ +{ imm_b , 0xfd, 0x03, 1024, "subi.b" , 0, ACC_BYTE }, /* 0000 010 000 */ +{ imm_w , 0xfd, 0x03, 1024, "subi.w" , 0, ACC_WORD }, /* 0000 010 001 */ +{ imm_l , 0xfd, 0x03, 1024, "subi.l" , 0, ACC_LONG }, /* 0000 010 010 */ +{ chkcmp2 , 0xe4, 0x0f, 1058, "c 2.l" , 0, ACC_LONG }, /* 0000 010 011 */ +{ bit_reg , 0xfd, 0x1f, 1037, "btst" , 2, 0 }, /* 0000 010 100 */ +{ bit_reg , 0xfd, 0x03, 1037, "bchg" , 2, 0 }, /* 0000 010 101 */ +{ bit_reg , 0xfd, 0x03, 1037, "bclr" , 2, 0 }, /* 0000 010 110 */ +{ bit_reg , 0xfd, 0x03, 1037, "bset" , 2, 0 }, /* 0000 010 111 */ +{ imm_b , 0xfd, 0x03, 1024, "addi.b" , 0, ACC_BYTE }, /* 0000 011 000 */ +{ imm_w , 0xfd, 0x03, 1024, "addi.w" , 0, ACC_WORD }, /* 0000 011 001 */ +{ imm_l , 0xfd, 0x03, 1024, "addi.l" , 0, ACC_LONG }, /* 0000 011 010 */ +{ imm_b , 0xe4, 0x0f, 1027, "callm" , 0, 0 }, /* 0000 011 011 */ +{ bit_reg , 0xfd, 0x1f, 1037, "btst" , 3, 0 }, /* 0000 011 100 */ +{ bit_reg , 0xfd, 0x03, 1037, "bchg" , 3, 0 }, /* 0000 011 101 */ +{ bit_reg , 0xfd, 0x03, 1037, "bclr" , 3, 0 }, /* 0000 011 110 */ +{ bit_reg , 0xfd, 0x03, 1037, "bset" , 3, 0 }, /* 0000 011 111 */ +{ bit_imm , 0xfd, 0x0f, 1024, "btst" , 0, 0 }, /* 0000 100 000 */ +{ bit_imm , 0xfd, 0x03, 1024, "bchg" , 0, 0 }, /* 0000 100 001 */ +{ bit_imm , 0xfd, 0x03, 1024, "bclr" , 0, 0 }, /* 0000 100 010 */ +{ bit_imm , 0xfd, 0x03, 1024, "bset" , 0, 0 }, /* 0000 100 011 */ +{ bit_reg , 0xfd, 0x1f, 1037, "btst" , 4, 0 }, /* 0000 100 100 */ +{ bit_reg , 0xfd, 0x03, 1037, "bchg" , 4, 0 }, /* 0000 100 101 */ +{ bit_reg , 0xfd, 0x03, 1037, "bclr" , 4, 0 }, /* 0000 100 110 */ +{ bit_reg , 0xfd, 0x03, 1037, "bset" , 4, 0 }, /* 0000 100 111 */ +{ imm_b , 0xfd, 0x03, 1026, "eori.b" , 0, ACC_BYTE }, /* 0000 101 000 */ +{ imm_w , 0xfd, 0x03, 1026, "eori.w" , 0, ACC_WORD }, /* 0000 101 001 */ +{ imm_l , 0xfd, 0x03, 1024, "eori.l" , 0, ACC_LONG }, /* 0000 101 010 */ +{ cas , 0xfc, 0x03, 1040, "cas.b" , 0, ACC_BYTE }, /* 0000 101 011 */ +{ bit_reg , 0xfd, 0x1f, 1037, "btst" , 5, 0 }, /* 0000 101 100 */ +{ bit_reg , 0xfd, 0x03, 1037, "bchg" , 5, 0 }, /* 0000 101 101 */ +{ bit_reg , 0xfd, 0x03, 1037, "bclr" , 5, 0 }, /* 0000 101 110 */ +{ bit_reg , 0xfd, 0x03, 1037, "bset" , 5, 0 }, /* 0000 101 111 */ +{ imm_b , 0xfd, 0x0f, 1024, "cmpi.b" , 0, ACC_BYTE }, /* 0000 110 000 */ +{ imm_w , 0xfd, 0x0f, 1024, "cmpi.w" , 0, ACC_WORD }, /* 0000 110 001 */ +{ imm_l , 0xfd, 0x0f, 1024, "cmpi.l" , 0, ACC_LONG }, /* 0000 110 010 */ +{ cas , 0xfc, 0x03, 1041, "cas.w" , 0, ACC_WORD }, /* 0000 110 011 */ +{ bit_reg , 0xfd, 0x1f, 1037, "btst" , 6, 0 }, /* 0000 110 100 */ +{ bit_reg , 0xfd, 0x03, 1037, "bchg" , 6, 0 }, /* 0000 110 101 */ +{ bit_reg , 0xfd, 0x03, 1037, "bclr" , 6, 0 }, /* 0000 110 110 */ +{ bit_reg , 0xfd, 0x03, 1037, "bset" , 6, 0 }, /* 0000 110 111 */ +{ moves , 0xfc, 0x03, 1024, "moves.b" , 0, ACC_BYTE }, /* 0000 111 000 */ +{ moves , 0xfc, 0x03, 1024, "moves.w" , 0, ACC_WORD }, /* 0000 111 001 */ +{ moves , 0xfc, 0x03, 1024, "moves.l" , 0, ACC_LONG }, /* 0000 111 010 */ +{ cas , 0xfc, 0x03, 1042, "cas.l" , 0, ACC_LONG }, /* 0000 111 011 */ +{ bit_reg , 0xfd, 0x1f, 1037, "btst" , 7, 0 }, /* 0000 111 100 */ +{ bit_reg , 0xfd, 0x03, 1037, "bchg" , 7, 0 }, /* 0000 111 101 */ +{ bit_reg , 0xfd, 0x03, 1037, "bclr" , 7, 0 }, /* 0000 111 110 */ +{ bit_reg , 0xfd, 0x03, 1037, "bset" , 7, 0 }, /* 0000 111 111 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "move.b" , 0, ACC_BYTE }, /* 0001 000 000 */ +{ invalid , 0xff, 0xff, 1024, 0 , 0, 0 }, /* 0001 000 001 */ +{ move , 0xff, 0x1f, 1024, "move.b" , 0, ACC_BYTE }, /* 0001 000 010 */ +{ move , 0xff, 0x1f, 1024, "move.b" , 0, ACC_BYTE }, /* 0001 000 011 */ +{ move , 0xff, 0x1f, 1024, "move.b" , 0, ACC_BYTE }, /* 0001 000 100 */ +{ move , 0xff, 0x1f, 1024, "move.b" , 0, ACC_BYTE }, /* 0001 000 101 */ +{ move , 0xff, 0x1f, 1024, "move.b" , 0, ACC_BYTE }, /* 0001 000 110 */ +{ move , 0xff, 0x1f, 1024, "move.b" , 0, ACC_BYTE }, /* 0001 000 111 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "move.b" , 1, ACC_BYTE }, /* 0001 001 000 */ +{ invalid , 0xff, 0xff, 1024, 0 , 1, 0 }, /* 0001 001 001 */ +{ move , 0xff, 0x1f, 1024, "move.b" , 0, ACC_BYTE }, /* 0001 001 010 */ +{ move , 0xff, 0x1f, 1024, "move.b" , 0, ACC_BYTE }, /* 0001 001 011 */ +{ move , 0xff, 0x1f, 1024, "move.b" , 0, ACC_BYTE }, /* 0001 001 100 */ +{ move , 0xff, 0x1f, 1024, "move.b" , 0, ACC_BYTE }, /* 0001 001 101 */ +{ move , 0xff, 0x1f, 1024, "move.b" , 0, ACC_BYTE }, /* 0001 001 110 */ +{ move , 0xff, 0x1f, 1024, "move.b" , 0, ACC_BYTE }, /* 0001 001 111 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "move.b" , 2, ACC_BYTE }, /* 0001 010 000 */ +{ invalid , 0xff, 0xff, 1024, 0 , 2, 0 }, /* 0001 010 001 */ +{ move , 0xff, 0x1f, 1024, "move.b" , 0, ACC_BYTE }, /* 0001 010 010 */ +{ move , 0xff, 0x1f, 1024, "move.b" , 0, ACC_BYTE }, /* 0001 010 011 */ +{ move , 0xff, 0x1f, 1024, "move.b" , 0, ACC_BYTE }, /* 0001 010 100 */ +{ move , 0xff, 0x1f, 1024, "move.b" , 0, ACC_BYTE }, /* 0001 010 101 */ +{ move , 0xff, 0x1f, 1024, "move.b" , 0, ACC_BYTE }, /* 0001 010 110 */ +{ invalid , 0xff, 0xff, 1024, 0 , 2, 0 }, /* 0001 010 111 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "move.b" , 3, ACC_BYTE }, /* 0001 011 000 */ +{ invalid , 0xff, 0xff, 1024, 0 , 3, 0 }, /* 0001 011 001 */ +{ move , 0xff, 0x1f, 1024, "move.b" , 0, ACC_BYTE }, /* 0001 011 010 */ +{ move , 0xff, 0x1f, 1024, "move.b" , 0, ACC_BYTE }, /* 0001 011 011 */ +{ move , 0xff, 0x1f, 1024, "move.b" , 0, ACC_BYTE }, /* 0001 011 100 */ +{ move , 0xff, 0x1f, 1024, "move.b" , 0, ACC_BYTE }, /* 0001 011 101 */ +{ move , 0xff, 0x1f, 1024, "move.b" , 0, ACC_BYTE }, /* 0001 011 110 */ +{ invalid , 0xff, 0xff, 1024, 0 , 3, 0 }, /* 0001 011 111 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "move.b" , 4, ACC_BYTE }, /* 0001 100 000 */ +{ invalid , 0xff, 0xff, 1024, 0 , 4, 0 }, /* 0001 100 001 */ +{ move , 0xff, 0x1f, 1024, "move.b" , 0, ACC_BYTE }, /* 0001 100 010 */ +{ move , 0xff, 0x1f, 1024, "move.b" , 0, ACC_BYTE }, /* 0001 100 011 */ +{ move , 0xff, 0x1f, 1024, "move.b" , 0, ACC_BYTE }, /* 0001 100 100 */ +{ move , 0xff, 0x1f, 1024, "move.b" , 0, ACC_BYTE }, /* 0001 100 101 */ +{ move , 0xff, 0x1f, 1024, "move.b" , 0, ACC_BYTE }, /* 0001 100 110 */ +{ invalid , 0xff, 0xff, 1024, 0 , 4, 0 }, /* 0001 100 111 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "move.b" , 5, ACC_BYTE }, /* 0001 101 000 */ +{ invalid , 0xff, 0xff, 1024, 0 , 5, 0 }, /* 0001 101 001 */ +{ move , 0xff, 0x1f, 1024, "move.b" , 0, ACC_BYTE }, /* 0001 101 010 */ +{ move , 0xff, 0x1f, 1024, "move.b" , 0, ACC_BYTE }, /* 0001 101 011 */ +{ move , 0xff, 0x1f, 1024, "move.b" , 0, ACC_BYTE }, /* 0001 101 100 */ +{ move , 0xff, 0x1f, 1024, "move.b" , 0, ACC_BYTE }, /* 0001 101 101 */ +{ move , 0xff, 0x1f, 1024, "move.b" , 0, ACC_BYTE }, /* 0001 101 110 */ +{ invalid , 0xff, 0xff, 1024, 0 , 5, 0 }, /* 0001 101 111 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "move.b" , 6, ACC_BYTE }, /* 0001 110 000 */ +{ invalid , 0xff, 0xff, 1024, 0 , 6, 0 }, /* 0001 110 001 */ +{ move , 0xff, 0x1f, 1024, "move.b" , 0, ACC_BYTE }, /* 0001 110 010 */ +{ move , 0xff, 0x1f, 1024, "move.b" , 0, ACC_BYTE }, /* 0001 110 011 */ +{ move , 0xff, 0x1f, 1024, "move.b" , 0, ACC_BYTE }, /* 0001 110 100 */ +{ move , 0xff, 0x1f, 1024, "move.b" , 0, ACC_BYTE }, /* 0001 110 101 */ +{ move , 0xff, 0x1f, 1024, "move.b" , 0, ACC_BYTE }, /* 0001 110 110 */ +{ invalid , 0xff, 0xff, 1024, 0 , 6, 0 }, /* 0001 110 111 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "move.b" , 7, ACC_BYTE }, /* 0001 111 000 */ +{ invalid , 0xff, 0xff, 1024, 0 , 7, 0 }, /* 0001 111 001 */ +{ move , 0xff, 0x1f, 1024, "move.b" , 0, ACC_BYTE }, /* 0001 111 010 */ +{ move , 0xff, 0x1f, 1024, "move.b" , 0, ACC_BYTE }, /* 0001 111 011 */ +{ move , 0xff, 0x1f, 1024, "move.b" , 0, ACC_BYTE }, /* 0001 111 100 */ +{ move , 0xff, 0x1f, 1024, "move.b" , 0, ACC_BYTE }, /* 0001 111 101 */ +{ move , 0xff, 0x1f, 1024, "move.b" , 0, ACC_BYTE }, /* 0001 111 110 */ +{ invalid , 0xff, 0xff, 1024, 0 , 7, 0 }, /* 0001 111 111 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "move.l" , 0, ACC_LONG }, /* 0010 000 000 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "movea.l" , 8, ACC_LONG }, /* 0010 000 001 */ +{ move , 0xff, 0x1f, 1024, "move.l" , 0, ACC_LONG }, /* 0010 000 010 */ +{ move , 0xff, 0x1f, 1024, "move.l" , 0, ACC_LONG }, /* 0010 000 011 */ +{ move , 0xff, 0x1f, 1024, "move.l" , 0, ACC_LONG }, /* 0010 000 100 */ +{ move , 0xff, 0x1f, 1024, "move.l" , 0, ACC_LONG }, /* 0010 000 101 */ +{ move , 0xff, 0x1f, 1024, "move.l" , 0, ACC_LONG }, /* 0010 000 110 */ +{ move , 0xff, 0x1f, 1024, "move.l" , 0, ACC_LONG }, /* 0010 000 111 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "move.l" , 1, ACC_LONG }, /* 0010 001 000 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "movea.l" , 9, ACC_LONG }, /* 0010 001 001 */ +{ move , 0xff, 0x1f, 1024, "move.l" , 0, ACC_LONG }, /* 0010 001 010 */ +{ move , 0xff, 0x1f, 1024, "move.l" , 0, ACC_LONG }, /* 0010 001 011 */ +{ move , 0xff, 0x1f, 1024, "move.l" , 0, ACC_LONG }, /* 0010 001 100 */ +{ move , 0xff, 0x1f, 1024, "move.l" , 0, ACC_LONG }, /* 0010 001 101 */ +{ move , 0xff, 0x1f, 1024, "move.l" , 0, ACC_LONG }, /* 0010 001 110 */ +{ move , 0xff, 0x1f, 1024, "move.l" , 0, ACC_LONG }, /* 0010 001 111 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "move.l" , 2, ACC_LONG }, /* 0010 010 000 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "movea.l" ,10, ACC_LONG }, /* 0010 010 001 */ +{ move , 0xff, 0x1f, 1024, "move.l" , 0, ACC_LONG }, /* 0010 010 010 */ +{ move , 0xff, 0x1f, 1024, "move.l" , 0, ACC_LONG }, /* 0010 010 011 */ +{ move , 0xff, 0x1f, 1024, "move.l" , 0, ACC_LONG }, /* 0010 010 100 */ +{ move , 0xff, 0x1f, 1024, "move.l" , 0, ACC_LONG }, /* 0010 010 101 */ +{ move , 0xff, 0x1f, 1024, "move.l" , 0, ACC_LONG }, /* 0010 010 110 */ +{ invalid , 0xff, 0xff, 1024, 0 , 2, 0 }, /* 0010 010 111 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "move.l" , 3, ACC_LONG }, /* 0010 011 000 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "movea.l" ,11, ACC_LONG }, /* 0010 011 001 */ +{ move , 0xff, 0x1f, 1024, "move.l" , 0, ACC_LONG }, /* 0010 011 010 */ +{ move , 0xff, 0x1f, 1024, "move.l" , 0, ACC_LONG }, /* 0010 011 011 */ +{ move , 0xff, 0x1f, 1024, "move.l" , 0, ACC_LONG }, /* 0010 011 100 */ +{ move , 0xff, 0x1f, 1024, "move.l" , 0, ACC_LONG }, /* 0010 011 101 */ +{ move , 0xff, 0x1f, 1024, "move.l" , 0, ACC_LONG }, /* 0010 011 110 */ +{ invalid , 0xff, 0xff, 1024, 0 , 3, 0 }, /* 0010 011 111 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "move.l" , 4, ACC_LONG }, /* 0010 100 000 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "movea.l" ,12, ACC_LONG }, /* 0010 100 001 */ +{ move , 0xff, 0x1f, 1024, "move.l" , 0, ACC_LONG }, /* 0010 100 010 */ +{ move , 0xff, 0x1f, 1024, "move.l" , 0, ACC_LONG }, /* 0010 100 011 */ +{ move , 0xff, 0x1f, 1024, "move.l" , 0, ACC_LONG }, /* 0010 100 100 */ +{ move , 0xff, 0x1f, 1024, "move.l" , 0, ACC_LONG }, /* 0010 100 101 */ +{ move , 0xff, 0x1f, 1024, "move.l" , 0, ACC_LONG }, /* 0010 100 110 */ +{ invalid , 0xff, 0xff, 1024, 0 , 4, 0 }, /* 0010 100 111 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "move.l" , 5, ACC_LONG }, /* 0010 101 000 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "movea.l" ,13, ACC_LONG }, /* 0010 101 001 */ +{ move , 0xff, 0x1f, 1024, "move.l" , 0, ACC_LONG }, /* 0010 101 010 */ +{ move , 0xff, 0x1f, 1024, "move.l" , 0, ACC_LONG }, /* 0010 101 011 */ +{ move , 0xff, 0x1f, 1024, "move.l" , 0, ACC_LONG }, /* 0010 101 100 */ +{ move , 0xff, 0x1f, 1024, "move.l" , 0, ACC_LONG }, /* 0010 101 101 */ +{ move , 0xff, 0x1f, 1024, "move.l" , 0, ACC_LONG }, /* 0010 101 110 */ +{ invalid , 0xff, 0xff, 1024, 0 , 5, 0 }, /* 0010 101 111 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "move.l" , 6, ACC_LONG }, /* 0010 110 000 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "movea.l" ,14, ACC_LONG }, /* 0010 110 001 */ +{ move , 0xff, 0x1f, 1024, "move.l" , 0, ACC_LONG }, /* 0010 110 010 */ +{ move , 0xff, 0x1f, 1024, "move.l" , 0, ACC_LONG }, /* 0010 110 011 */ +{ move , 0xff, 0x1f, 1024, "move.l" , 0, ACC_LONG }, /* 0010 110 100 */ +{ move , 0xff, 0x1f, 1024, "move.l" , 0, ACC_LONG }, /* 0010 110 101 */ +{ move , 0xff, 0x1f, 1024, "move.l" , 0, ACC_LONG }, /* 0010 110 110 */ +{ invalid , 0xff, 0xff, 1024, 0 , 6, 0 }, /* 0010 110 111 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "move.l" , 7, ACC_LONG }, /* 0010 111 000 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "movea.l" ,15, ACC_LONG }, /* 0010 111 001 */ +{ move , 0xff, 0x1f, 1024, "move.l" , 0, ACC_LONG }, /* 0010 111 010 */ +{ move , 0xff, 0x1f, 1024, "move.l" , 0, ACC_LONG }, /* 0010 111 011 */ +{ move , 0xff, 0x1f, 1024, "move.l" , 0, ACC_LONG }, /* 0010 111 100 */ +{ move , 0xff, 0x1f, 1024, "move.l" , 0, ACC_LONG }, /* 0010 111 101 */ +{ move , 0xff, 0x1f, 1024, "move.l" , 0, ACC_LONG }, /* 0010 111 110 */ +{ invalid , 0xff, 0xff, 1024, 0 , 7, 0 }, /* 0010 111 111 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "move.w" , 0, ACC_WORD }, /* 0011 000 000 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "movea.w" , 8, ACC_WORD }, /* 0011 000 001 */ +{ move , 0xff, 0x1f, 1024, "move.w" , 0, ACC_WORD }, /* 0011 000 010 */ +{ move , 0xff, 0x1f, 1024, "move.w" , 0, ACC_WORD }, /* 0011 000 011 */ +{ move , 0xff, 0x1f, 1024, "move.w" , 0, ACC_WORD }, /* 0011 000 100 */ +{ move , 0xff, 0x1f, 1024, "move.w" , 0, ACC_WORD }, /* 0011 000 101 */ +{ move , 0xff, 0x1f, 1024, "move.w" , 0, ACC_WORD }, /* 0011 000 110 */ +{ move , 0xff, 0x1f, 1024, "move.w" , 0, ACC_WORD }, /* 0011 000 111 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "move.w" , 1, ACC_WORD }, /* 0011 001 000 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "movea.w" , 9, ACC_WORD }, /* 0011 001 001 */ +{ move , 0xff, 0x1f, 1024, "move.w" , 0, ACC_WORD }, /* 0011 001 010 */ +{ move , 0xff, 0x1f, 1024, "move.w" , 0, ACC_WORD }, /* 0011 001 011 */ +{ move , 0xff, 0x1f, 1024, "move.w" , 0, ACC_WORD }, /* 0011 001 100 */ +{ move , 0xff, 0x1f, 1024, "move.w" , 0, ACC_WORD }, /* 0011 001 101 */ +{ move , 0xff, 0x1f, 1024, "move.w" , 0, ACC_WORD }, /* 0011 001 110 */ +{ move , 0xff, 0x1f, 1024, "move.w" , 0, ACC_WORD }, /* 0011 001 111 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "move.w" , 2, ACC_WORD }, /* 0011 010 000 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "movea.w" ,10, ACC_WORD }, /* 0011 010 001 */ +{ move , 0xff, 0x1f, 1024, "move.w" , 0, ACC_WORD }, /* 0011 010 010 */ +{ move , 0xff, 0x1f, 1024, "move.w" , 0, ACC_WORD }, /* 0011 010 011 */ +{ move , 0xff, 0x1f, 1024, "move.w" , 0, ACC_WORD }, /* 0011 010 100 */ +{ move , 0xff, 0x1f, 1024, "move.w" , 0, ACC_WORD }, /* 0011 010 101 */ +{ move , 0xff, 0x1f, 1024, "move.w" , 0, ACC_WORD }, /* 0011 010 110 */ +{ invalid , 0xff, 0xff, 1024, 0 , 2, 0 }, /* 0011 010 111 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "move.w" , 3, ACC_WORD }, /* 0011 011 000 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "movea.w" ,11, ACC_WORD }, /* 0011 011 001 */ +{ move , 0xff, 0x1f, 1024, "move.w" , 0, ACC_WORD }, /* 0011 011 010 */ +{ move , 0xff, 0x1f, 1024, "move.w" , 0, ACC_WORD }, /* 0011 011 011 */ +{ move , 0xff, 0x1f, 1024, "move.w" , 0, ACC_WORD }, /* 0011 011 100 */ +{ move , 0xff, 0x1f, 1024, "move.w" , 0, ACC_WORD }, /* 0011 011 101 */ +{ move , 0xff, 0x1f, 1024, "move.w" , 0, ACC_WORD }, /* 0011 011 110 */ +{ invalid , 0xff, 0xff, 1024, 0 , 3, 0 }, /* 0011 011 111 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "move.w" , 4, ACC_WORD }, /* 0011 100 000 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "movea.w" ,12, ACC_WORD }, /* 0011 100 001 */ +{ move , 0xff, 0x1f, 1024, "move.w" , 0, ACC_WORD }, /* 0011 100 010 */ +{ move , 0xff, 0x1f, 1024, "move.w" , 0, ACC_WORD }, /* 0011 100 011 */ +{ move , 0xff, 0x1f, 1024, "move.w" , 0, ACC_WORD }, /* 0011 100 100 */ +{ move , 0xff, 0x1f, 1024, "move.w" , 0, ACC_WORD }, /* 0011 100 101 */ +{ move , 0xff, 0x1f, 1024, "move.w" , 0, ACC_WORD }, /* 0011 100 110 */ +{ invalid , 0xff, 0xff, 1024, 0 , 4, 0 }, /* 0011 100 111 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "move.w" , 5, ACC_WORD }, /* 0011 101 000 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "movea.w" ,13, ACC_WORD }, /* 0011 101 001 */ +{ move , 0xff, 0x1f, 1024, "move.w" , 0, ACC_WORD }, /* 0011 101 010 */ +{ move , 0xff, 0x1f, 1024, "move.w" , 0, ACC_WORD }, /* 0011 101 011 */ +{ move , 0xff, 0x1f, 1024, "move.w" , 0, ACC_WORD }, /* 0011 101 100 */ +{ move , 0xff, 0x1f, 1024, "move.w" , 0, ACC_WORD }, /* 0011 101 101 */ +{ move , 0xff, 0x1f, 1024, "move.w" , 0, ACC_WORD }, /* 0011 101 110 */ +{ invalid , 0xff, 0xff, 1024, 0 , 5, 0 }, /* 0011 101 111 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "move.w" , 6, ACC_WORD }, /* 0011 110 000 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "movea.w" ,14, ACC_WORD }, /* 0011 110 001 */ +{ move , 0xff, 0x1f, 1024, "move.w" , 0, ACC_WORD }, /* 0011 110 010 */ +{ move , 0xff, 0x1f, 1024, "move.w" , 0, ACC_WORD }, /* 0011 110 011 */ +{ move , 0xff, 0x1f, 1024, "move.w" , 0, ACC_WORD }, /* 0011 110 100 */ +{ move , 0xff, 0x1f, 1024, "move.w" , 0, ACC_WORD }, /* 0011 110 101 */ +{ move , 0xff, 0x1f, 1024, "move.w" , 0, ACC_WORD }, /* 0011 110 110 */ +{ invalid , 0xff, 0xff, 1024, 0 , 6, 0 }, /* 0011 110 111 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "move.w" , 7, ACC_WORD }, /* 0011 111 000 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "movea.w" ,15, ACC_WORD }, /* 0011 111 001 */ +{ move , 0xff, 0x1f, 1024, "move.w" , 0, ACC_WORD }, /* 0011 111 010 */ +{ move , 0xff, 0x1f, 1024, "move.w" , 0, ACC_WORD }, /* 0011 111 011 */ +{ move , 0xff, 0x1f, 1024, "move.w" , 0, ACC_WORD }, /* 0011 111 100 */ +{ move , 0xff, 0x1f, 1024, "move.w" , 0, ACC_WORD }, /* 0011 111 101 */ +{ move , 0xff, 0x1f, 1024, "move.w" , 0, ACC_WORD }, /* 0011 111 110 */ +{ invalid , 0xff, 0xff, 1024, 0 , 7, 0 }, /* 0011 111 111 */ +{ op1 , 0xfd, 0x03, 1024, "negx.b" , 0, ACC_BYTE }, /* 0100 000 000 */ +{ op1 , 0xfd, 0x03, 1024, "negx.w" , 0, ACC_WORD }, /* 0100 000 001 */ +{ op1 , 0xfd, 0x03, 1024, "negx.l" , 0, ACC_LONG }, /* 0100 000 010 */ +{ movesrccr, 0xfd, 0x03, 1024, "move.w", FROM_SR, ACC_WORD }, /* 0100 000 011 */ +{ EA_to_Rn , 0xfd, 0x1f, 1024, "chk.l" , 0, ACC_LONG }, /* 0100 000 100 */ +{ invalid , 0xff, 0xff, 1024, 0 , 0, 0 }, /* 0100 000 101 */ +{ EA_to_Rn , 0xfd, 0x1f, 1024, "chk.w" , 0, ACC_WORD }, /* 0100 000 110 */ +{ EA_to_Rn , 0xe4, 0x0f, 1024, "lea" , 8, ACC_UNKNOWN }, /* 0100 000 111 */ +{ op1 , 0xfd, 0x03, 1024, "clr.b" , 0, ACC_BYTE }, /* 0100 001 000 */ +{ op1 , 0xfd, 0x03, 1024, "clr.w" , 0, ACC_WORD }, /* 0100 001 001 */ +{ op1 , 0xfd, 0x03, 1024, "clr.l" , 0, ACC_LONG }, /* 0100 001 010 */ +{ movesrccr, 0xfd, 0x03, 1024, "move.w", FROM_CCR, ACC_WORD}, /* 0100 001 011 */ +{ EA_to_Rn , 0xfd, 0x1f, 1024, "chk.l" , 1, ACC_LONG }, /* 0100 001 100 */ +{ invalid , 0xff, 0xff, 1024, 0 , 0, 0 }, /* 0100 001 101 */ +{ EA_to_Rn , 0xfd, 0x1f, 1024, "chk.w" , 1, ACC_WORD }, /* 0100 001 110 */ +{ EA_to_Rn , 0xe4, 0x0f, 1024, "lea" , 9, ACC_UNKNOWN }, /* 0100 001 111 */ +{ op1 , 0xfd, 0x03, 1024, "neg.b" , 0, ACC_BYTE }, /* 0100 010 000 */ +{ op1 , 0xfd, 0x03, 1024, "neg.w" , 0, ACC_WORD }, /* 0100 010 001 */ +{ op1 , 0xfd, 0x03, 1024, "neg.l" , 0, ACC_LONG }, /* 0100 010 010 */ +{ movesrccr, 0xfd, 0x1f, 1024, "move.w", TO_CCR, ACC_WORD }, /* 0100 010 011 */ +{ EA_to_Rn , 0xfd, 0x1f, 1024, "chk.l" , 2, ACC_LONG }, /* 0100 010 100 */ +{ invalid , 0xff, 0xff, 1024, 0 , 0, 0 }, /* 0100 010 101 */ +{ EA_to_Rn , 0xfd, 0x1f, 1024, "chk.w" , 2, ACC_WORD }, /* 0100 010 110 */ +{ EA_to_Rn , 0xe4, 0x0f, 1024, "lea" ,10, ACC_UNKNOWN }, /* 0100 010 111 */ +{ op1 , 0xfd, 0x03, 1024, "not.b" , 0, ACC_BYTE }, /* 0100 011 000 */ +{ op1 , 0xfd, 0x03, 1024, "not.w" , 0, ACC_WORD }, /* 0100 011 001 */ +{ op1 , 0xfd, 0x03, 1024, "not.l" , 0, ACC_LONG }, /* 0100 011 010 */ +{ movesrccr, 0xfd, 0x1f, 1024, "move.w", TO_SR, ACC_WORD }, /* 0100 011 011 */ +{ EA_to_Rn , 0xfd, 0x1f, 1024, "chk.l" , 3, ACC_LONG }, /* 0100 011 100 */ +{ invalid , 0xff, 0xff, 1024, 0 , 0, 0 }, /* 0100 011 101 */ +{ EA_to_Rn , 0xfd, 0x1f, 1024, "chk.w" , 3, ACC_WORD }, /* 0100 011 110 */ +{ EA_to_Rn , 0xe4, 0x0f, 1024, "lea" ,11, ACC_UNKNOWN }, /* 0100 011 111 */ +{ op1 , 0xfd, 0x03, 1055, "nbcd.b" , 0, ACC_BYTE }, /* 0100 100 000 */ +{ op1 , 0xe4, 0x0f, 1029, "pea" , 0, ACC_UNKNOWN }, /* 0100 100 001 */ +{ movem , 0xf4, 0x03, 1030, "movem.w", REG_TO_MEM, 0 }, /* 0100 100 010 */ +{ movem , 0xf4, 0x03, 1050, "movem.l", REG_TO_MEM, 0 }, /* 0100 100 011 */ +{ EA_to_Rn , 0xfd, 0x1f, 1024, "chk.l" , 4, ACC_LONG }, /* 0100 100 100 */ +{ invalid , 0xff, 0xff, 1024, 0 , 0, 0 }, /* 0100 100 101 */ +{ EA_to_Rn , 0xfd, 0x1f, 1024, "chk.w" , 4, ACC_WORD }, /* 0100 100 110 */ +{ EA_to_Rn , 0xe4, 0x0f, 1051, "lea" ,12, ACC_UNKNOWN }, /* 0100 100 111 */ +{ op1 , 0xff, 0x1f, 1024, "tst.b" , 0, ACC_BYTE }, /* 0100 101 000 */ +{ op1 , 0xff, 0x1f, 1024, "tst.w" , 0, ACC_WORD }, /* 0100 101 001 */ +{ op1 , 0xff, 0x1f, 1024, "tst.l" , 0, ACC_LONG }, /* 0100 101 010 */ +{ op1 , 0xfd, 0x03, 1025, "tas" , 0, ACC_BYTE }, /* 0100 101 011 */ +{ EA_to_Rn , 0xfd, 0x1f, 1024, "chk.l" , 5, ACC_LONG }, /* 0100 101 100 */ +{ invalid , 0xff, 0xff, 1024, 0 , 0, 0 }, /* 0100 101 101 */ +{ EA_to_Rn , 0xfd, 0x1f, 1024, "chk.w" , 5, ACC_WORD }, /* 0100 101 110 */ +{ EA_to_Rn , 0xe4, 0x0f, 1024, "lea" ,13, ACC_UNKNOWN }, /* 0100 101 111 */ +{ muldivl , 0xfd, 0x1f, 1024, "mul " , 0, ACC_LONG }, /* 0100 110 000 */ +{ muldivl , 0xfd, 0x1f, 1024, "div " , 0, ACC_LONG }, /* 0100 110 001 */ +{ movem , 0xec, 0x0f, 1059, "movem.w" , MEM_TO_REG, 0 }, /* 0100 110 010 */ +{ movem , 0xec, 0x0f, 1024, "movem.l" , MEM_TO_REG, 0 }, /* 0100 110 011 */ +{ EA_to_Rn , 0xfd, 0x1f, 1024, "chk.l" , 6, ACC_LONG }, /* 0100 110 100 */ +{ invalid , 0xff, 0xff, 1024, 0 , 0, 0 }, /* 0100 110 101 */ +{ EA_to_Rn , 0xfd, 0x1f, 1024, "chk.w" , 6, ACC_WORD }, /* 0100 110 110 */ +{ EA_to_Rn , 0xe4, 0x0f, 1024, "lea" ,14, ACC_UNKNOWN }, /* 0100 110 111 */ +{ invalid , 0xff, 0xff, 1024, 0 , 0, 0 }, /* 0100 111 000 */ +{ special , 0xff, 0x0c, 1024, 0 , 0, 0 }, /* 0100 111 001 */ +{ op1 , 0xe4, 0x0f, 1024, "jsr" , 0, ACC_CODE }, /* 0100 111 010 */ +{ op1_end , 0xe4, 0x0f, 1024, "jmp" , 0, ACC_CODE }, /* 0100 111 011 */ +{ EA_to_Rn , 0xfd, 0x1f, 1024, "chk.l" , 7, ACC_LONG }, /* 0100 111 100 */ +{ invalid , 0xff, 0xff, 1024, 0 , 0, 0 }, /* 0100 111 101 */ +{ EA_to_Rn , 0xfd, 0x1f, 1024, "chk.w" , 7, ACC_WORD }, /* 0100 111 110 */ +{ EA_to_Rn , 0xe4, 0x0f, 1024, "lea" ,15, ACC_UNKNOWN }, /* 0100 111 111 */ +{ quick , 0xff, 0x03, 1024, "addq.b" , 8, ACC_BYTE }, /* 0101 000 000 */ +{ quick , 0xff, 0x03, 1024, "addq.w" , 8, ACC_WORD }, /* 0101 000 001 */ +{ quick , 0xff, 0x03, 1024, "addq.l" , 8, ACC_LONG }, /* 0101 000 010 */ +{ dbranch , 0x02, 0xff, 1046, "dbt" , 0, 0 }, /* 0101 000 011 */ +{ quick , 0xff, 0x03, 1024, "subq.b" , 8, ACC_BYTE }, /* 0101 000 100 */ +{ quick , 0xff, 0x03, 1024, "subq.w" , 8, ACC_WORD }, /* 0101 000 101 */ +{ quick , 0xff, 0x03, 1024, "subq.l" , 8, ACC_LONG }, /* 0101 000 110 */ +{ dbranch , 0x02, 0xff, 1046, "dbra" , 0, 0 }, /* 0101 000 111 */ +{ quick , 0xff, 0x03, 1024, "addq.b" , 1, ACC_BYTE }, /* 0101 001 000 */ +{ quick , 0xff, 0x03, 1024, "addq.w" , 1, ACC_WORD }, /* 0101 001 001 */ +{ quick , 0xff, 0x03, 1024, "addq.l" , 1, ACC_LONG }, /* 0101 001 010 */ +{ dbranch , 0x02, 0xff, 1046, "dbhi" , 1, 0 }, /* 0101 001 011 */ +{ quick , 0xff, 0x03, 1024, "subq.b" , 1, ACC_BYTE }, /* 0101 001 100 */ +{ quick , 0xff, 0x03, 1024, "subq.w" , 1, ACC_WORD }, /* 0101 001 101 */ +{ quick , 0xff, 0x03, 1024, "subq.l" , 1, ACC_LONG }, /* 0101 001 110 */ +{ dbranch , 0x02, 0xff, 1046, "dbls" , 1, 0 }, /* 0101 001 111 */ +{ quick , 0xff, 0x03, 1024, "addq.b" , 2, ACC_BYTE }, /* 0101 010 000 */ +{ quick , 0xff, 0x03, 1024, "addq.w" , 2, ACC_WORD }, /* 0101 010 001 */ +{ quick , 0xff, 0x03, 1024, "addq.l" , 2, ACC_LONG }, /* 0101 010 010 */ +{ dbranch , 0x02, 0xff, 1046, "dbcc" , 2, 0 }, /* 0101 010 011 */ +{ quick , 0xff, 0x03, 1024, "subq.b" , 2, ACC_BYTE }, /* 0101 010 100 */ +{ quick , 0xff, 0x03, 1024, "subq.w" , 2, ACC_WORD }, /* 0101 010 101 */ +{ quick , 0xff, 0x03, 1024, "subq.l" , 2, ACC_LONG }, /* 0101 010 110 */ +{ dbranch , 0x02, 0xff, 1046, "dbcs" , 2, 0 }, /* 0101 010 111 */ +{ quick , 0xff, 0x03, 1024, "addq.b" , 3, ACC_BYTE }, /* 0101 011 000 */ +{ quick , 0xff, 0x03, 1024, "addq.w" , 3, ACC_WORD }, /* 0101 011 001 */ +{ quick , 0xff, 0x03, 1024, "addq.l" , 3, ACC_LONG }, /* 0101 011 010 */ +{ dbranch , 0x02, 0xff, 1046, "dbne" , 3, 0 }, /* 0101 011 011 */ +{ quick , 0xff, 0x03, 1024, "subq.b" , 3, ACC_BYTE }, /* 0101 011 100 */ +{ quick , 0xff, 0x03, 1024, "subq.w" , 3, ACC_WORD }, /* 0101 011 101 */ +{ quick , 0xff, 0x03, 1024, "subq.l" , 3, ACC_LONG }, /* 0101 011 110 */ +{ dbranch , 0x02, 0xff, 1046, "dbeq" , 3, 0 }, /* 0101 011 111 */ +{ quick , 0xff, 0x03, 1024, "addq.b" , 4, ACC_BYTE }, /* 0101 100 000 */ +{ quick , 0xff, 0x03, 1024, "addq.w" , 4, ACC_WORD }, /* 0101 100 001 */ +{ quick , 0xff, 0x03, 1024, "addq.l" , 4, ACC_LONG }, /* 0101 100 010 */ +{ dbranch , 0x02, 0xff, 1046, "dbvc" , 4, 0 }, /* 0101 100 011 */ +{ quick , 0xff, 0x03, 1024, "subq.b" , 4, ACC_BYTE }, /* 0101 100 100 */ +{ quick , 0xff, 0x03, 1024, "subq.w" , 4, ACC_WORD }, /* 0101 100 101 */ +{ quick , 0xff, 0x03, 1024, "subq.l" , 4, ACC_LONG }, /* 0101 100 110 */ +{ dbranch , 0x02, 0xff, 1046, "dbvs" , 4, 0 }, /* 0101 100 111 */ +{ quick , 0xff, 0x03, 1024, "addq.b" , 5, ACC_BYTE }, /* 0101 101 000 */ +{ quick , 0xff, 0x03, 1024, "addq.w" , 5, ACC_WORD }, /* 0101 101 001 */ +{ quick , 0xff, 0x03, 1024, "addq.l" , 5, ACC_LONG }, /* 0101 101 010 */ +{ dbranch , 0x02, 0xff, 1046, "dbpl" , 5, 0 }, /* 0101 101 011 */ +{ quick , 0xff, 0x03, 1024, "subq.b" , 5, ACC_BYTE }, /* 0101 101 100 */ +{ quick , 0xff, 0x03, 1024, "subq.w" , 5, ACC_WORD }, /* 0101 101 101 */ +{ quick , 0xff, 0x03, 1024, "subq.l" , 5, ACC_LONG }, /* 0101 101 110 */ +{ dbranch , 0x02, 0xff, 1046, "dbmi" , 5, 0 }, /* 0101 101 111 */ +{ quick , 0xff, 0x03, 1024, "addq.b" , 6, ACC_BYTE }, /* 0101 110 000 */ +{ quick , 0xff, 0x03, 1024, "addq.w" , 6, ACC_WORD }, /* 0101 110 001 */ +{ quick , 0xff, 0x03, 1024, "addq.l" , 6, ACC_LONG }, /* 0101 110 010 */ +{ dbranch , 0x02, 0xff, 1046, "dbge" , 6, 0 }, /* 0101 110 011 */ +{ quick , 0xff, 0x03, 1024, "subq.b" , 6, ACC_BYTE }, /* 0101 110 100 */ +{ quick , 0xff, 0x03, 1024, "subq.w" , 6, ACC_WORD }, /* 0101 110 101 */ +{ quick , 0xff, 0x03, 1024, "subq.l" , 6, ACC_LONG }, /* 0101 110 110 */ +{ dbranch , 0x02, 0xff, 1046, "dble" , 6, 0 }, /* 0101 110 111 */ +{ quick , 0xff, 0x03, 1024, "addq.b" , 7, ACC_BYTE }, /* 0101 111 000 */ +{ quick , 0xff, 0x03, 1024, "addq.w" , 7, ACC_WORD }, /* 0101 111 001 */ +{ quick , 0xff, 0x03, 1024, "addq.l" , 7, ACC_LONG }, /* 0101 111 010 */ +{ dbranch , 0x02, 0xff, 1046, "dbgt" , 7, 0 }, /* 0101 111 011 */ +{ quick , 0xff, 0x03, 1024, "subq.b" , 7, ACC_BYTE }, /* 0101 111 100 */ +{ quick , 0xff, 0x03, 1024, "subq.w" , 7, ACC_WORD }, /* 0101 111 101 */ +{ quick , 0xff, 0x03, 1024, "subq.l" , 7, ACC_LONG }, /* 0101 111 110 */ +{ dbranch , 0x02, 0xff, 1046, "dble" , 7, 0 }, /* 0101 111 111 */ +{ branch , 0xff, 0xff, 1024, "bra" , 0, 0 }, /* 0110 000 000 */ +{ branch , 0xff, 0xff, 1024, "bra" , 0, 0 }, /* 0110 000 001 */ +{ branch , 0xff, 0xff, 1024, "bra" , 0, 0 }, /* 0110 000 010 */ +{ branch , 0xff, 0xff, 1024, "bra" , 0, 0 }, /* 0110 000 011 */ +{ branch , 0xff, 0xff, 1024, "bsr" , 0, 0 }, /* 0110 000 100 */ +{ branch , 0xff, 0xff, 1024, "bsr" , 0, 0 }, /* 0110 000 101 */ +{ branch , 0xff, 0xff, 1024, "bsr" , 0, 0 }, /* 0110 000 110 */ +{ branch , 0xff, 0xff, 1024, "bsr" , 0, 0 }, /* 0110 000 111 */ +{ branch , 0xff, 0xff, 1024, "bhi" , 0, 0 }, /* 0110 001 000 */ +{ branch , 0xff, 0xff, 1024, "bhi" , 0, 0 }, /* 0110 001 001 */ +{ branch , 0xff, 0xff, 1024, "bhi" , 0, 0 }, /* 0110 001 010 */ +{ branch , 0xff, 0xff, 1024, "bhi" , 0, 0 }, /* 0110 001 011 */ +{ branch , 0xff, 0xff, 1024, "bls" , 0, 0 }, /* 0110 001 100 */ +{ branch , 0xff, 0xff, 1024, "bls" , 0, 0 }, /* 0110 001 101 */ +{ branch , 0xff, 0xff, 1024, "bls" , 0, 0 }, /* 0110 001 110 */ +{ branch , 0xff, 0xff, 1024, "bls" , 0, 0 }, /* 0110 001 111 */ +{ branch , 0xff, 0xff, 1024, "bcc" , 0, 0 }, /* 0110 010 000 */ +{ branch , 0xff, 0xff, 1024, "bcc" , 0, 0 }, /* 0110 010 001 */ +{ branch , 0xff, 0xff, 1024, "bcc" , 0, 0 }, /* 0110 010 010 */ +{ branch , 0xff, 0xff, 1024, "bcc" , 0, 0 }, /* 0110 010 011 */ +{ branch , 0xff, 0xff, 1024, "bcs" , 0, 0 }, /* 0110 010 100 */ +{ branch , 0xff, 0xff, 1024, "bcs" , 0, 0 }, /* 0110 010 101 */ +{ branch , 0xff, 0xff, 1024, "bcs" , 0, 0 }, /* 0110 010 110 */ +{ branch , 0xff, 0xff, 1024, "bcs" , 0, 0 }, /* 0110 010 111 */ +{ branch , 0xff, 0xff, 1024, "bne" , 0, 0 }, /* 0110 011 000 */ +{ branch , 0xff, 0xff, 1024, "bne" , 0, 0 }, /* 0110 011 001 */ +{ branch , 0xff, 0xff, 1024, "bne" , 0, 0 }, /* 0110 011 010 */ +{ branch , 0xff, 0xff, 1024, "bne" , 0, 0 }, /* 0110 011 011 */ +{ branch , 0xff, 0xff, 1024, "beq" , 0, 0 }, /* 0110 011 100 */ +{ branch , 0xff, 0xff, 1024, "beq" , 0, 0 }, /* 0110 011 101 */ +{ branch , 0xff, 0xff, 1024, "beq" , 0, 0 }, /* 0110 011 110 */ +{ branch , 0xff, 0xff, 1024, "beq" , 0, 0 }, /* 0110 011 111 */ +{ branch , 0xff, 0xff, 1024, "bvc" , 0, 0 }, /* 0110 100 000 */ +{ branch , 0xff, 0xff, 1024, "bvc" , 0, 0 }, /* 0110 100 001 */ +{ branch , 0xff, 0xff, 1024, "bvc" , 0, 0 }, /* 0110 100 010 */ +{ branch , 0xff, 0xff, 1024, "bvc" , 0, 0 }, /* 0110 100 011 */ +{ branch , 0xff, 0xff, 1024, "bvs" , 0, 0 }, /* 0110 100 100 */ +{ branch , 0xff, 0xff, 1024, "bvs" , 0, 0 }, /* 0110 100 101 */ +{ branch , 0xff, 0xff, 1024, "bvs" , 0, 0 }, /* 0110 100 110 */ +{ branch , 0xff, 0xff, 1024, "bvs" , 0, 0 }, /* 0110 100 111 */ +{ branch , 0xff, 0xff, 1024, "bpl" , 0, 0 }, /* 0110 101 000 */ +{ branch , 0xff, 0xff, 1024, "bpl" , 0, 0 }, /* 0110 101 001 */ +{ branch , 0xff, 0xff, 1024, "bpl" , 0, 0 }, /* 0110 101 010 */ +{ branch , 0xff, 0xff, 1024, "bpl" , 0, 0 }, /* 0110 101 011 */ +{ branch , 0xff, 0xff, 1024, "bmi" , 0, 0 }, /* 0110 101 100 */ +{ branch , 0xff, 0xff, 1024, "bmi" , 0, 0 }, /* 0110 101 101 */ +{ branch , 0xff, 0xff, 1024, "bmi" , 0, 0 }, /* 0110 101 110 */ +{ branch , 0xff, 0xff, 1024, "bmi" , 0, 0 }, /* 0110 101 111 */ +{ branch , 0xff, 0xff, 1024, "bge" , 0, 0 }, /* 0110 110 000 */ +{ branch , 0xff, 0xff, 1024, "bge" , 0, 0 }, /* 0110 110 001 */ +{ branch , 0xff, 0xff, 1024, "bge" , 0, 0 }, /* 0110 110 010 */ +{ branch , 0xff, 0xff, 1024, "bge" , 0, 0 }, /* 0110 110 011 */ +{ branch , 0xff, 0xff, 1024, "blt" , 0, 0 }, /* 0110 110 100 */ +{ branch , 0xff, 0xff, 1024, "blt" , 0, 0 }, /* 0110 110 101 */ +{ branch , 0xff, 0xff, 1024, "blt" , 0, 0 }, /* 0110 110 110 */ +{ branch , 0xff, 0xff, 1024, "blt" , 0, 0 }, /* 0110 110 111 */ +{ branch , 0xff, 0xff, 1024, "bgt" , 0, 0 }, /* 0110 111 000 */ +{ branch , 0xff, 0xff, 1024, "bgt" , 0, 0 }, /* 0110 111 001 */ +{ branch , 0xff, 0xff, 1024, "bgt" , 0, 0 }, /* 0110 111 010 */ +{ branch , 0xff, 0xff, 1024, "bgt" , 0, 0 }, /* 0110 111 011 */ +{ branch , 0xff, 0xff, 1024, "ble" , 0, 0 }, /* 0110 111 100 */ +{ branch , 0xff, 0xff, 1024, "ble" , 0, 0 }, /* 0110 111 101 */ +{ branch , 0xff, 0xff, 1024, "ble" , 0, 0 }, /* 0110 111 110 */ +{ branch , 0xff, 0xff, 1024, "ble" , 0, 0 }, /* 0110 111 111 */ +{ moveq , 0xff, 0xff, 1024, "moveq" , 0, 0 }, /* 0111 000 000 */ +{ moveq , 0xff, 0xff, 1024, "moveq" , 0, 0 }, /* 0111 000 001 */ +{ moveq , 0xff, 0xff, 1024, "moveq" , 0, 0 }, /* 0111 000 010 */ +{ moveq , 0xff, 0xff, 1024, "moveq" , 0, 0 }, /* 0111 000 011 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "mvs.b" , 0, ACC_SBYTE }, /* 0111 000 100 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "mvs.w" , 0, ACC_SWORD }, /* 0111 000 101 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "mvz.b" , 0, ACC_BYTE }, /* 0111 000 110 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "mvz.w" , 0, ACC_WORD }, /* 0111 000 111 */ +{ moveq , 0xff, 0xff, 1024, "moveq" , 1, 0 }, /* 0111 001 000 */ +{ moveq , 0xff, 0xff, 1024, "moveq" , 1, 0 }, /* 0111 001 001 */ +{ moveq , 0xff, 0xff, 1024, "moveq" , 1, 0 }, /* 0111 001 010 */ +{ moveq , 0xff, 0xff, 1024, "moveq" , 1, 0 }, /* 0111 001 011 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "mvs.b" , 1, ACC_SBYTE }, /* 0111 001 100 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "mvs.w" , 1, ACC_SWORD }, /* 0111 001 101 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "mvz.b" , 1, ACC_BYTE }, /* 0111 001 110 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "mvz.w" , 1, ACC_WORD }, /* 0111 001 111 */ +{ moveq , 0xff, 0xff, 1024, "moveq" , 2, 0 }, /* 0111 010 000 */ +{ moveq , 0xff, 0xff, 1024, "moveq" , 2, 0 }, /* 0111 010 001 */ +{ moveq , 0xff, 0xff, 1024, "moveq" , 2, 0 }, /* 0111 010 010 */ +{ moveq , 0xff, 0xff, 1024, "moveq" , 2, 0 }, /* 0111 010 011 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "mvs.b" , 2, ACC_SBYTE }, /* 0111 010 100 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "mvs.w" , 2, ACC_SWORD }, /* 0111 010 101 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "mvz.b" , 2, ACC_BYTE }, /* 0111 010 110 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "mvz.w" , 2, ACC_WORD }, /* 0111 010 111 */ +{ moveq , 0xff, 0xff, 1024, "moveq" , 3, 0 }, /* 0111 011 000 */ +{ moveq , 0xff, 0xff, 1024, "moveq" , 3, 0 }, /* 0111 011 001 */ +{ moveq , 0xff, 0xff, 1024, "moveq" , 3, 0 }, /* 0111 011 010 */ +{ moveq , 0xff, 0xff, 1024, "moveq" , 3, 0 }, /* 0111 011 011 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "mvs.b" , 3, ACC_SBYTE }, /* 0111 011 100 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "mvs.w" , 3, ACC_SWORD }, /* 0111 011 101 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "mvz.b" , 3, ACC_BYTE }, /* 0111 011 110 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "mvz.w" , 3, ACC_WORD }, /* 0111 011 111 */ +{ moveq , 0xff, 0xff, 1024, "moveq" , 4, 0 }, /* 0111 100 000 */ +{ moveq , 0xff, 0xff, 1024, "moveq" , 4, 0 }, /* 0111 100 001 */ +{ moveq , 0xff, 0xff, 1024, "moveq" , 4, 0 }, /* 0111 100 010 */ +{ moveq , 0xff, 0xff, 1024, "moveq" , 4, 0 }, /* 0111 100 011 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "mvs.b" , 4, ACC_SBYTE }, /* 0111 100 100 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "mvs.w" , 4, ACC_SWORD }, /* 0111 100 101 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "mvz.b" , 4, ACC_BYTE }, /* 0111 100 110 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "mvz.w" , 4, ACC_WORD }, /* 0111 100 111 */ +{ moveq , 0xff, 0xff, 1024, "moveq" , 5, 0 }, /* 0111 101 000 */ +{ moveq , 0xff, 0xff, 1024, "moveq" , 5, 0 }, /* 0111 101 001 */ +{ moveq , 0xff, 0xff, 1024, "moveq" , 5, 0 }, /* 0111 101 010 */ +{ moveq , 0xff, 0xff, 1024, "moveq" , 5, 0 }, /* 0111 101 011 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "mvs.b" , 5, ACC_SBYTE }, /* 0111 101 100 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "mvs.w" , 5, ACC_SWORD }, /* 0111 101 101 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "mvz.b" , 5, ACC_BYTE }, /* 0111 101 110 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "mvz.w" , 5, ACC_WORD }, /* 0111 101 111 */ +{ moveq , 0xff, 0xff, 1024, "moveq" , 6, 0 }, /* 0111 110 000 */ +{ moveq , 0xff, 0xff, 1024, "moveq" , 6, 0 }, /* 0111 110 001 */ +{ moveq , 0xff, 0xff, 1024, "moveq" , 6, 0 }, /* 0111 110 010 */ +{ moveq , 0xff, 0xff, 1024, "moveq" , 6, 0 }, /* 0111 110 011 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "mvs.b" , 6, ACC_SBYTE }, /* 0111 110 100 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "mvs.w" , 6, ACC_SWORD }, /* 0111 110 101 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "mvz.b" , 6, ACC_BYTE }, /* 0111 110 110 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "mvz.w" , 6, ACC_WORD }, /* 0111 110 111 */ +{ moveq , 0xff, 0xff, 1024, "moveq" , 7, 0 }, /* 0111 111 000 */ +{ moveq , 0xff, 0xff, 1024, "moveq" , 7, 0 }, /* 0111 111 001 */ +{ moveq , 0xff, 0xff, 1024, "moveq" , 7, 0 }, /* 0111 111 010 */ +{ moveq , 0xff, 0xff, 1024, "moveq" , 7, 0 }, /* 0111 111 011 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "mvs.b" , 7, ACC_SBYTE }, /* 0111 111 100 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "mvs.w" , 7, ACC_SWORD }, /* 0111 111 101 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "mvz.b" , 7, ACC_BYTE }, /* 0111 111 110 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "mvz.w" , 7, ACC_WORD }, /* 0111 111 111 */ +{ EA_to_Rn , 0xfd, 0x1f, 1024, "or.b" , 0, ACC_BYTE }, /* 1000 000 000 */ +{ EA_to_Rn , 0xfd, 0x1f, 1024, "or.w" , 0, ACC_WORD }, /* 1000 000 001 */ +{ EA_to_Rn , 0xfd, 0x1f, 1024, "or.l" , 0, ACC_LONG }, /* 1000 000 010 */ +{ EA_to_Rn , 0xfd, 0x1f, 1024, "divu.w" , 0, ACC_WORD }, /* 1000 000 011 */ +{ Rn_to_EA , 0xfc, 0x03, 1031, "or.b" , 0, ACC_BYTE }, /* 1000 000 100 */ +{ Rn_to_EA , 0xfc, 0x03, 1032, "or.w" , 0, ACC_WORD }, /* 1000 000 101 */ +{ Rn_to_EA , 0xfc, 0x03, 1028, "or.l" , 0, ACC_LONG }, /* 1000 000 110 */ +{ EA_to_Rn , 0xfd, 0x1f, 1024, "divs.w" , 0, ACC_SWORD }, /* 1000 000 111 */ +{ EA_to_Rn , 0xfd, 0x1f, 1024, "or.b" , 1, ACC_BYTE }, /* 1000 001 000 */ +{ EA_to_Rn , 0xfd, 0x1f, 1024, "or.w" , 1, ACC_WORD }, /* 1000 001 001 */ +{ EA_to_Rn , 0xfd, 0x1f, 1024, "or.l" , 1, ACC_LONG }, /* 1000 001 010 */ +{ EA_to_Rn , 0xfd, 0x1f, 1024, "divu.w" , 1, ACC_WORD }, /* 1000 001 011 */ +{ Rn_to_EA , 0xfc, 0x03, 1031, "or.b" , 1, ACC_BYTE }, /* 1000 001 100 */ +{ Rn_to_EA , 0xfc, 0x03, 1032, "or.w" , 1, ACC_WORD }, /* 1000 001 101 */ +{ Rn_to_EA , 0xfc, 0x03, 1028, "or.l" , 1, ACC_LONG }, /* 1000 001 110 */ +{ EA_to_Rn , 0xfd, 0x1f, 1024, "divs.w" , 1, ACC_SWORD }, /* 1000 001 111 */ +{ EA_to_Rn , 0xfd, 0x1f, 1024, "or.b" , 2, ACC_BYTE }, /* 1000 010 000 */ +{ EA_to_Rn , 0xfd, 0x1f, 1024, "or.w" , 2, ACC_WORD }, /* 1000 010 001 */ +{ EA_to_Rn , 0xfd, 0x1f, 1024, "or.l" , 2, ACC_LONG }, /* 1000 010 010 */ +{ EA_to_Rn , 0xfd, 0x1f, 1024, "divu.w" , 2, ACC_WORD }, /* 1000 010 011 */ +{ Rn_to_EA , 0xfc, 0x03, 1031, "or.b" , 2, ACC_BYTE }, /* 1000 010 100 */ +{ Rn_to_EA , 0xfc, 0x03, 1032, "or.w" , 2, ACC_WORD }, /* 1000 010 101 */ +{ Rn_to_EA , 0xfc, 0x03, 1028, "or.l" , 2, ACC_LONG }, /* 1000 010 110 */ +{ EA_to_Rn , 0xfd, 0x1f, 1024, "divs.w" , 2, ACC_SWORD }, /* 1000 010 111 */ +{ EA_to_Rn , 0xfd, 0x1f, 1024, "or.b" , 3, ACC_BYTE }, /* 1000 011 000 */ +{ EA_to_Rn , 0xfd, 0x1f, 1024, "or.w" , 3, ACC_WORD }, /* 1000 011 001 */ +{ EA_to_Rn , 0xfd, 0x1f, 1024, "or.l" , 3, ACC_LONG }, /* 1000 011 010 */ +{ EA_to_Rn , 0xfd, 0x1f, 1024, "divu.w" , 3, ACC_WORD }, /* 1000 011 011 */ +{ Rn_to_EA , 0xfc, 0x03, 1031, "or.b" , 3, ACC_BYTE }, /* 1000 011 100 */ +{ Rn_to_EA , 0xfc, 0x03, 1032, "or.w" , 3, ACC_WORD }, /* 1000 011 101 */ +{ Rn_to_EA , 0xfc, 0x03, 1028, "or.l" , 3, ACC_LONG }, /* 1000 011 110 */ +{ EA_to_Rn , 0xfd, 0x1f, 1024, "divs.w" , 3, ACC_SWORD }, /* 1000 011 111 */ +{ EA_to_Rn , 0xfd, 0x1f, 1024, "or.b" , 4, ACC_BYTE }, /* 1000 100 000 */ +{ EA_to_Rn , 0xfd, 0x1f, 1024, "or.w" , 4, ACC_WORD }, /* 1000 100 001 */ +{ EA_to_Rn , 0xfd, 0x1f, 1024, "or.l" , 4, ACC_LONG }, /* 1000 100 010 */ +{ EA_to_Rn , 0xfd, 0x1f, 1024, "divu.w" , 4, ACC_WORD }, /* 1000 100 011 */ +{ Rn_to_EA , 0xfc, 0x03, 1031, "or.b" , 4, ACC_BYTE }, /* 1000 100 100 */ +{ Rn_to_EA , 0xfc, 0x03, 1032, "or.w" , 4, ACC_WORD }, /* 1000 100 101 */ +{ Rn_to_EA , 0xfc, 0x03, 1028, "or.l" , 4, ACC_LONG }, /* 1000 100 110 */ +{ EA_to_Rn , 0xfd, 0x1f, 1024, "divs.w" , 4, ACC_SWORD }, /* 1000 100 111 */ +{ EA_to_Rn , 0xfd, 0x1f, 1024, "or.b" , 5, ACC_BYTE }, /* 1000 101 000 */ +{ EA_to_Rn , 0xfd, 0x1f, 1024, "or.w" , 5, ACC_WORD }, /* 1000 101 001 */ +{ EA_to_Rn , 0xfd, 0x1f, 1024, "or.l" , 5, ACC_LONG }, /* 1000 101 010 */ +{ EA_to_Rn , 0xfd, 0x1f, 1024, "divu.w" , 5, ACC_WORD }, /* 1000 101 011 */ +{ Rn_to_EA , 0xfc, 0x03, 1031, "or.b" , 5, ACC_BYTE }, /* 1000 101 100 */ +{ Rn_to_EA , 0xfc, 0x03, 1032, "or.w" , 5, ACC_WORD }, /* 1000 101 101 */ +{ Rn_to_EA , 0xfc, 0x03, 1028, "or.l" , 5, ACC_LONG }, /* 1000 101 110 */ +{ EA_to_Rn , 0xfd, 0x1f, 1024, "divs.w" , 5, ACC_SWORD }, /* 1000 101 111 */ +{ EA_to_Rn , 0xfd, 0x1f, 1024, "or.b" , 6, ACC_BYTE }, /* 1000 110 000 */ +{ EA_to_Rn , 0xfd, 0x1f, 1024, "or.w" , 6, ACC_WORD }, /* 1000 110 001 */ +{ EA_to_Rn , 0xfd, 0x1f, 1024, "or.l" , 6, ACC_LONG }, /* 1000 110 00 */ +{ EA_to_Rn , 0xfd, 0x1f, 1024, "divu.w" , 6, ACC_WORD }, /* 1000 110 011 */ +{ Rn_to_EA , 0xfc, 0x03, 1031, "or.b" , 6, ACC_BYTE }, /* 1000 110 100 */ +{ Rn_to_EA , 0xfc, 0x03, 1032, "or.w" , 6, ACC_WORD }, /* 1000 110 101 */ +{ Rn_to_EA , 0xfc, 0x03, 1028, "or.l" , 6, ACC_LONG }, /* 1000 110 110 */ +{ EA_to_Rn , 0xfd, 0x1f, 1024, "divs.w" , 6, ACC_SWORD }, /* 1000 110 111 */ +{ EA_to_Rn , 0xfd, 0x1f, 1024, "or.b" , 7, ACC_BYTE }, /* 1000 111 000 */ +{ EA_to_Rn , 0xfd, 0x1f, 1024, "or.w" , 7, ACC_WORD }, /* 1000 111 001 */ +{ EA_to_Rn , 0xfd, 0x1f, 1024, "or.l" , 7, ACC_LONG }, /* 1000 111 010 */ +{ EA_to_Rn , 0xfd, 0x1f, 1024, "divu.w" , 7, ACC_WORD }, /* 1000 111 011 */ +{ Rn_to_EA , 0xfc, 0x03, 1031, "or.b" , 7, ACC_BYTE }, /* 1000 111 100 */ +{ Rn_to_EA , 0xfc, 0x03, 1032, "or.w" , 7, ACC_WORD }, /* 1000 111 101 */ +{ Rn_to_EA , 0xfc, 0x03, 1028, "or.l" , 7, ACC_LONG }, /* 1000 111 110 */ +{ EA_to_Rn , 0xfd, 0x1f, 1024, "divs.w" , 7, ACC_SWORD }, /* 1000 111 111 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "sub.b" , 0, ACC_BYTE }, /* 1001 000 000 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "sub.w" , 0, ACC_WORD }, /* 1001 000 001 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "sub.l" , 0, ACC_LONG }, /* 1001 000 010 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "suba.w" , 8, ACC_WORD }, /* 1001 000 011 */ +{ Rn_to_EA , 0xfc, 0x03, 1052, "sub.b" , 0, ACC_BYTE }, /* 1001 000 100 */ +{ Rn_to_EA , 0xfc, 0x03, 1053, "sub.w" , 0, ACC_WORD }, /* 1001 000 101 */ +{ Rn_to_EA , 0xfc, 0x03, 1054, "sub.l" , 0, ACC_LONG }, /* 1001 000 110 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "suba.l" , 8, ACC_LONG }, /* 1001 000 111 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "sub.b" , 1, ACC_BYTE }, /* 1001 001 000 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "sub.w" , 1, ACC_WORD }, /* 1001 001 001 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "sub.l" , 1, ACC_LONG }, /* 1001 001 010 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "suba.w" , 9, ACC_WORD }, /* 1001 001 011 */ +{ Rn_to_EA , 0xfc, 0x03, 1052, "sub.b" , 1, ACC_BYTE }, /* 1001 001 100 */ +{ Rn_to_EA , 0xfc, 0x03, 1053, "sub.w" , 1, ACC_WORD }, /* 1001 001 101 */ +{ Rn_to_EA , 0xfc, 0x03, 1054, "sub.l" , 1, ACC_LONG }, /* 1001 001 110 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "suba.l" , 9, ACC_LONG }, /* 1001 001 111 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "sub.b" , 2, ACC_BYTE }, /* 1001 010 000 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "sub.w" , 2, ACC_WORD }, /* 1001 010 001 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "sub.l" , 2, ACC_LONG }, /* 1001 010 010 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "suba.w" ,10, ACC_WORD }, /* 1001 010 011 */ +{ Rn_to_EA , 0xfc, 0x03, 1052, "sub.b" , 2, ACC_BYTE }, /* 1001 010 100 */ +{ Rn_to_EA , 0xfc, 0x03, 1053, "sub.w" , 2, ACC_WORD }, /* 1001 010 101 */ +{ Rn_to_EA , 0xfc, 0x03, 1054, "sub.l" , 2, ACC_LONG }, /* 1001 010 110 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "suba.l" ,10, ACC_LONG }, /* 1001 010 111 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "sub.b" , 3, ACC_BYTE }, /* 1001 011 000 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "sub.w" , 3, ACC_WORD }, /* 1001 011 001 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "sub.l" , 3, ACC_LONG }, /* 1001 011 010 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "suba.w" ,11, ACC_WORD }, /* 1001 011 011 */ +{ Rn_to_EA , 0xfc, 0x03, 1052, "sub.b" , 3, ACC_BYTE }, /* 1001 011 100 */ +{ Rn_to_EA , 0xfc, 0x03, 1053, "sub.w" , 3, ACC_WORD }, /* 1001 011 101 */ +{ Rn_to_EA , 0xfc, 0x03, 1054, "sub.l" , 3, ACC_LONG }, /* 1001 011 110 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "suba.l" ,11, ACC_LONG }, /* 1001 011 111 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "sub.b" , 4, ACC_BYTE }, /* 1001 100 000 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "sub.w" , 4, ACC_WORD }, /* 1001 100 001 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "sub.l" , 4, ACC_LONG }, /* 1001 100 010 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "suba.w" ,12, ACC_WORD }, /* 1001 100 011 */ +{ Rn_to_EA , 0xfc, 0x03, 1052, "sub.b" , 4, ACC_BYTE }, /* 1001 100 100 */ +{ Rn_to_EA , 0xfc, 0x03, 1053, "sub.w" , 4, ACC_WORD }, /* 1001 100 101 */ +{ Rn_to_EA , 0xfc, 0x03, 1054, "sub.l" , 4, ACC_LONG }, /* 1001 100 110 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "suba.l" ,12, ACC_LONG }, /* 1001 100 111 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "sub.b" , 5, ACC_BYTE }, /* 1001 101 000 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "sub.w" , 5, ACC_WORD }, /* 1001 101 001 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "sub.l" , 5, ACC_LONG }, /* 1001 101 010 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "suba.w" ,13, ACC_WORD }, /* 1001 101 011 */ +{ Rn_to_EA , 0xfc, 0x03, 1052, "sub.b" , 5, ACC_BYTE }, /* 1001 101 100 */ +{ Rn_to_EA , 0xfc, 0x03, 1053, "sub.w" , 5, ACC_WORD }, /* 1001 101 101 */ +{ Rn_to_EA , 0xfc, 0x03, 1054, "sub.l" , 5, ACC_LONG }, /* 1001 101 110 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "suba.l" ,13, ACC_LONG }, /* 1001 101 111 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "sub.b" , 6, ACC_BYTE }, /* 1001 110 000 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "sub.w" , 6, ACC_WORD }, /* 1001 110 001 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "sub.l" , 6, ACC_LONG }, /* 1001 110 010 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "suba.w" ,14, ACC_WORD }, /* 1001 110 011 */ +{ Rn_to_EA , 0xfc, 0x03, 1052, "sub.b" , 6, ACC_BYTE }, /* 1001 110 100 */ +{ Rn_to_EA , 0xfc, 0x03, 1053, "sub.w" , 6, ACC_WORD }, /* 1001 110 101 */ +{ Rn_to_EA , 0xfc, 0x03, 1054, "sub.l" , 6, ACC_LONG }, /* 1001 110 110 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "suba.l" ,14, ACC_LONG }, /* 1001 110 111 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "sub.b" , 7, ACC_BYTE }, /* 1001 111 000 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "sub.w" , 7, ACC_WORD }, /* 1001 111 001 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "sub.l" , 7, ACC_LONG }, /* 1001 111 010 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "suba.w" ,15, ACC_WORD }, /* 1001 111 011 */ +{ Rn_to_EA , 0xfc, 0x03, 1052, "sub.b" , 7, ACC_BYTE }, /* 1001 111 100 */ +{ Rn_to_EA , 0xfc, 0x03, 1053, "sub.w" , 7, ACC_WORD }, /* 1001 111 101 */ +{ Rn_to_EA , 0xfc, 0x03, 1054, "sub.l" , 7, ACC_LONG }, /* 1001 111 110 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "suba.l" ,15, ACC_LONG }, /* 1001 111 111 */ +{ invalid , 0xff, 0xff, 1024, 0 , 0, 0 }, /* 1010 000 000 */ +{ invalid , 0xff, 0xff, 1024, 0 , 0, 0 }, /* 1010 000 001 */ +{ invalid , 0xff, 0xff, 1024, 0 , 0, 0 }, /* 1010 000 010 */ +{ invalid , 0xff, 0xff, 1024, 0 , 0, 0 }, /* 1010 000 011 */ +{ invalid , 0xff, 0xff, 1024, 0 , 0, 0 }, /* 1010 000 100 */ +{ mov3q , 0xff, 0x0f, 1024, "mov3q" , 0, ACC_LONG }, /* 1010 000 101 */ +{ invalid , 0xff, 0xff, 1024, 0 , 0, 0 }, /* 1010 000 110 */ +{ invalid , 0xff, 0xff, 1024, 0 , 0, 0 }, /* 1010 000 111 */ +{ invalid , 0xff, 0xff, 1024, 0 , 0, 0 }, /* 1010 001 000 */ +{ invalid , 0xff, 0xff, 1024, 0 , 0, 0 }, /* 1010 001 001 */ +{ invalid , 0xff, 0xff, 1024, 0 , 0, 0 }, /* 1010 001 010 */ +{ invalid , 0xff, 0xff, 1024, 0 , 0, 0 }, /* 1010 001 011 */ +{ invalid , 0xff, 0xff, 1024, 0 , 0, 0 }, /* 1010 001 100 */ +{ mov3q , 0xff, 0x0f, 1024, "mov3q" , 1, ACC_LONG }, /* 1010 001 101 */ +{ invalid , 0xff, 0xff, 1024, 0 , 0, 0 }, /* 1010 001 110 */ +{ invalid , 0xff, 0xff, 1024, 0 , 0, 0 }, /* 1010 001 111 */ +{ invalid , 0xff, 0xff, 1024, 0 , 0, 0 }, /* 1010 010 000 */ +{ invalid , 0xff, 0xff, 1024, 0 , 0, 0 }, /* 1010 010 001 */ +{ invalid , 0xff, 0xff, 1024, 0 , 0, 0 }, /* 1010 010 010 */ +{ invalid , 0xff, 0xff, 1024, 0 , 0, 0 }, /* 1010 010 011 */ +{ invalid , 0xff, 0xff, 1024, 0 , 0, 0 }, /* 1010 010 100 */ +{ mov3q , 0xff, 0x0f, 1024, "mov3q" , 2, ACC_LONG }, /* 1010 010 101 */ +{ invalid , 0xff, 0xff, 1024, 0 , 0, 0 }, /* 1010 010 110 */ +{ invalid , 0xff, 0xff, 1024, 0 , 0, 0 }, /* 1010 010 111 */ +{ invalid , 0xff, 0xff, 1024, 0 , 0, 0 }, /* 1010 011 000 */ +{ invalid , 0xff, 0xff, 1024, 0 , 0, 0 }, /* 1010 011 001 */ +{ invalid , 0xff, 0xff, 1024, 0 , 0, 0 }, /* 1010 011 010 */ +{ invalid , 0xff, 0xff, 1024, 0 , 0, 0 }, /* 1010 011 011 */ +{ invalid , 0xff, 0xff, 1024, 0 , 0, 0 }, /* 1010 011 100 */ +{ mov3q , 0xff, 0x0f, 1024, "mov3q" , 3, ACC_LONG }, /* 1010 011 101 */ +{ invalid , 0xff, 0xff, 1024, 0 , 0, 0 }, /* 1010 011 110 */ +{ invalid , 0xff, 0xff, 1024, 0 , 0, 0 }, /* 1010 011 111 */ +{ invalid , 0xff, 0xff, 1024, 0 , 0, 0 }, /* 1010 100 000 */ +{ invalid , 0xff, 0xff, 1024, 0 , 0, 0 }, /* 1010 100 001 */ +{ invalid , 0xff, 0xff, 1024, 0 , 0, 0 }, /* 1010 100 010 */ +{ invalid , 0xff, 0xff, 1024, 0 , 0, 0 }, /* 1010 100 011 */ +{ invalid , 0xff, 0xff, 1024, 0 , 0, 0 }, /* 1010 100 100 */ +{ mov3q , 0xff, 0x0f, 1024, "mov3q" , 4, ACC_LONG }, /* 1010 100 101 */ +{ invalid , 0xff, 0xff, 1024, 0 , 0, 0 }, /* 1010 100 110 */ +{ invalid , 0xff, 0xff, 1024, 0 , 0, 0 }, /* 1010 100 111 */ +{ invalid , 0xff, 0xff, 1024, 0 , 0, 0 }, /* 1010 101 000 */ +{ invalid , 0xff, 0xff, 1024, 0 , 0, 0 }, /* 1010 101 001 */ +{ invalid , 0xff, 0xff, 1024, 0 , 0, 0 }, /* 1010 101 010 */ +{ invalid , 0xff, 0xff, 1024, 0 , 0, 0 }, /* 1010 101 011 */ +{ invalid , 0xff, 0xff, 1024, 0 , 0, 0 }, /* 1010 101 100 */ +{ mov3q , 0xff, 0x0f, 1024, "mov3q" , 5, ACC_LONG }, /* 1010 101 101 */ +{ invalid , 0xff, 0xff, 1024, 0 , 0, 0 }, /* 1010 101 110 */ +{ invalid , 0xff, 0xff, 1024, 0 , 0, 0 }, /* 1010 101 111 */ +{ invalid , 0xff, 0xff, 1024, 0 , 0, 0 }, /* 1010 110 000 */ +{ invalid , 0xff, 0xff, 1024, 0 , 0, 0 }, /* 1010 110 001 */ +{ invalid , 0xff, 0xff, 1024, 0 , 0, 0 }, /* 1010 110 010 */ +{ invalid , 0xff, 0xff, 1024, 0 , 0, 0 }, /* 1010 110 011 */ +{ invalid , 0xff, 0xff, 1024, 0 , 0, 0 }, /* 1010 110 100 */ +{ mov3q , 0xff, 0x0f, 1024, "mov3q" , 6, ACC_LONG }, /* 1010 110 101 */ +{ invalid , 0xff, 0xff, 1024, 0 , 0, 0 }, /* 1010 110 110 */ +{ invalid , 0xff, 0xff, 1024, 0 , 0, 0 }, /* 1010 110 111 */ +{ invalid , 0xff, 0xff, 1024, 0 , 0, 0 }, /* 1010 111 000 */ +{ invalid , 0xff, 0xff, 1024, 0 , 0, 0 }, /* 1010 111 001 */ +{ invalid , 0xff, 0xff, 1024, 0 , 0, 0 }, /* 1010 111 010 */ +{ invalid , 0xff, 0xff, 1024, 0 , 0, 0 }, /* 1010 111 011 */ +{ invalid , 0xff, 0xff, 1024, 0 , 0, 0 }, /* 1010 111 100 */ +{ mov3q , 0xff, 0x0f, 1024, "mov3q" , 7, ACC_LONG }, /* 1010 111 101 */ +{ invalid , 0xff, 0xff, 1024, 0 , 0, 0 }, /* 1010 111 110 */ +{ invalid , 0xff, 0xff, 1024, 0 , 0, 0 }, /* 1010 111 111 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "cmp.b" , 0, ACC_BYTE }, /* 1011 000 000 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "cmp.w" , 0, ACC_WORD }, /* 1011 000 001 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "cmp.l" , 0, ACC_LONG }, /* 1011 000 010 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "cmpa.w" , 8, ACC_WORD }, /* 1011 000 011 */ +{ Rn_to_EA , 0xfd, 0x03, 1034, "eor.b" , 0, ACC_BYTE }, /* 1011 000 100 */ +{ Rn_to_EA , 0xfd, 0x03, 1043, "eor.w" , 0, ACC_WORD }, /* 1011 000 101 */ +{ Rn_to_EA , 0xfd, 0x03, 1044, "eor.l" , 0, ACC_LONG }, /* 1011 000 110 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "cmpa.l" , 8, ACC_LONG }, /* 1011 000 111 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "cmp.b" , 1, ACC_BYTE }, /* 1011 001 000 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "cmp.w" , 1, ACC_WORD }, /* 1011 001 001 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "cmp.l" , 1, ACC_LONG }, /* 1011 001 010 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "cmpa.w" , 9, ACC_WORD }, /* 1011 001 011 */ +{ Rn_to_EA , 0xfd, 0x03, 1034, "eor.b" , 1, ACC_BYTE }, /* 1011 001 100 */ +{ Rn_to_EA , 0xfd, 0x03, 1043, "eor.w" , 1, ACC_WORD }, /* 1011 001 101 */ +{ Rn_to_EA , 0xfd, 0x03, 1044, "eor.l" , 1, ACC_LONG }, /* 1011 001 110 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "cmpa.l" , 9, ACC_LONG }, /* 1011 001 111 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "cmp.b" , 2, ACC_BYTE }, /* 1011 010 000 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "cmp.w" , 2, ACC_WORD }, /* 1011 010 001 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "cmp.l" , 2, ACC_LONG }, /* 1011 010 010 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "cmpa.w" ,10, ACC_WORD }, /* 1011 010 011 */ +{ Rn_to_EA , 0xfd, 0x03, 1034, "eor.b" , 2, ACC_BYTE }, /* 1011 010 100 */ +{ Rn_to_EA , 0xfd, 0x03, 1043, "eor.w" , 2, ACC_WORD }, /* 1011 010 101 */ +{ Rn_to_EA , 0xfd, 0x03, 1044, "eor.l" , 2, ACC_LONG }, /* 1011 010 110 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "cmpa.l" ,10, ACC_LONG }, /* 1011 010 111 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "cmp.b" , 3, ACC_BYTE }, /* 1011 011 000 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "cmp.w" , 3, ACC_WORD }, /* 1011 011 001 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "cmp.l" , 3, ACC_LONG }, /* 1011 011 010 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "cmpa.w" ,11, ACC_WORD }, /* 1011 011 011 */ +{ Rn_to_EA , 0xfd, 0x03, 1034, "eor.b" , 3, ACC_BYTE }, /* 1011 011 100 */ +{ Rn_to_EA , 0xfd, 0x03, 1043, "eor.w" , 3, ACC_WORD }, /* 1011 011 101 */ +{ Rn_to_EA , 0xfd, 0x03, 1044, "eor.l" , 3, ACC_LONG }, /* 1011 011 110 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "cmpa.l" ,11, ACC_LONG }, /* 1011 011 111 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "cmp.b" , 4, ACC_BYTE }, /* 1011 100 000 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "cmp.w" , 4, ACC_WORD }, /* 1011 100 001 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "cmp.l" , 4, ACC_LONG }, /* 1011 100 010 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "cmpa.w" ,12, ACC_WORD }, /* 1011 100 011 */ +{ Rn_to_EA , 0xfd, 0x03, 1034, "eor.b" , 4, ACC_BYTE }, /* 1011 100 100 */ +{ Rn_to_EA , 0xfd, 0x03, 1043, "eor.w" , 4, ACC_WORD }, /* 1011 100 101 */ +{ Rn_to_EA , 0xfd, 0x03, 1044, "eor.l" , 4, ACC_LONG }, /* 1011 100 110 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "cmpa.l" ,12, ACC_LONG }, /* 1011 100 111 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "cmp.b" , 5, ACC_BYTE }, /* 1011 101 000 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "cmp.w" , 5, ACC_WORD }, /* 1011 101 001 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "cmp.l" , 5, ACC_LONG }, /* 1011 101 010 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "cmpa.w" ,13, ACC_WORD }, /* 1011 101 011 */ +{ Rn_to_EA , 0xfd, 0x03, 1034, "eor.b" , 5, ACC_BYTE }, /* 1011 101 100 */ +{ Rn_to_EA , 0xfd, 0x03, 1043, "eor.w" , 5, ACC_WORD }, /* 1011 101 101 */ +{ Rn_to_EA , 0xfd, 0x03, 1044, "eor.l" , 5, ACC_LONG }, /* 1011 101 110 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "cmpa.l" ,13, ACC_LONG }, /* 1011 101 111 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "cmp.b" , 6, ACC_BYTE }, /* 1011 110 000 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "cmp.w" , 6, ACC_WORD }, /* 1011 110 001 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "cmp.l" , 6, ACC_LONG }, /* 1011 110 010 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "cmpa.w" ,14, ACC_WORD }, /* 1011 110 011 */ +{ Rn_to_EA , 0xfd, 0x03, 1034, "eor.b" , 6, ACC_BYTE }, /* 1011 110 100 */ +{ Rn_to_EA , 0xfd, 0x03, 1043, "eor.w" , 6, ACC_WORD }, /* 1011 110 101 */ +{ Rn_to_EA , 0xfd, 0x03, 1044, "eor.l" , 6, ACC_LONG }, /* 1011 110 110 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "cmpa.l" ,14, ACC_LONG }, /* 1011 110 111 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "cmp.b" , 7, ACC_BYTE }, /* 1011 111 000 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "cmp.w" , 7, ACC_WORD }, /* 1011 111 001 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "cmp.l" , 7, ACC_LONG }, /* 1011 111 010 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "cmpa.w" ,15, ACC_WORD }, /* 1011 111 011 */ +{ Rn_to_EA , 0xfd, 0x03, 1034, "eor.b" , 7, ACC_BYTE }, /* 1011 111 100 */ +{ Rn_to_EA , 0xfd, 0x03, 1043, "eor.w" , 7, ACC_WORD }, /* 1011 111 101 */ +{ Rn_to_EA , 0xfd, 0x03, 1044, "eor.l" , 7, ACC_LONG }, /* 1011 111 110 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "cmpa.l" ,15, ACC_LONG }, /* 1011 111 111 */ +{ EA_to_Rn , 0xfd, 0x1f, 1024, "and.b" , 0, ACC_BYTE }, /* 1100 000 000 */ +{ EA_to_Rn , 0xfd, 0x1f, 1024, "and.w" , 0, ACC_WORD }, /* 1100 000 001 */ +{ EA_to_Rn , 0xfd, 0x1f, 1024, "and.l" , 0, ACC_LONG }, /* 1100 000 010 */ +{ EA_to_Rn , 0xfd, 0x1f, 1024, "mulu.w" , 0, ACC_WORD }, /* 1100 000 011 */ +{ Rn_to_EA , 0xfc, 0x03, 1035, "and.b" , 0, ACC_BYTE }, /* 1100 000 100 */ +{ Rn_to_EA , 0xfc, 0x03, 1036, "and.w" , 0, ACC_WORD }, /* 1100 000 101 */ +{ Rn_to_EA , 0xfc, 0x03, 1036, "and.l" , 0, ACC_LONG }, /* 1100 000 110 */ +{ EA_to_Rn , 0xfd, 0x1f, 1024, "muls.w" , 0, ACC_SWORD }, /* 1100 000 111 */ +{ EA_to_Rn , 0xfd, 0x1f, 1024, "and.b" , 1, ACC_BYTE }, /* 1100 001 000 */ +{ EA_to_Rn , 0xfd, 0x1f, 1024, "and.w" , 1, ACC_WORD }, /* 1100 001 001 */ +{ EA_to_Rn , 0xfd, 0x1f, 1024, "and.l" , 1, ACC_LONG }, /* 1100 001 010 */ +{ EA_to_Rn , 0xfd, 0x1f, 1024, "mulu.w" , 1, ACC_WORD }, /* 1100 001 011 */ +{ Rn_to_EA , 0xfc, 0x03, 1035, "and.b" , 1, ACC_BYTE }, /* 1100 001 100 */ +{ Rn_to_EA , 0xfc, 0x03, 1036, "and.w" , 1, ACC_WORD }, /* 1100 001 101 */ +{ Rn_to_EA , 0xfc, 0x03, 1036, "and.l" , 1, ACC_LONG }, /* 1100 001 110 */ +{ EA_to_Rn , 0xfd, 0x1f, 1024, "muls.w" , 1, ACC_SWORD }, /* 1100 001 111 */ +{ EA_to_Rn , 0xfd, 0x1f, 1024, "and.b" , 2, ACC_BYTE }, /* 1100 010 000 */ +{ EA_to_Rn , 0xfd, 0x1f, 1024, "and.w" , 2, ACC_WORD }, /* 1100 010 001 */ +{ EA_to_Rn , 0xfd, 0x1f, 1024, "and.l" , 2, ACC_LONG }, /* 1100 010 010 */ +{ EA_to_Rn , 0xfd, 0x1f, 1024, "mulu.w" , 2, ACC_WORD }, /* 1100 010 011 */ +{ Rn_to_EA , 0xfc, 0x03, 1035, "and.b" , 2, ACC_BYTE }, /* 1100 010 100 */ +{ Rn_to_EA , 0xfc, 0x03, 1036, "and.w" , 2, ACC_WORD }, /* 1100 010 101 */ +{ Rn_to_EA , 0xfc, 0x03, 1036, "and.l" , 2, ACC_LONG }, /* 1100 010 110 */ +{ EA_to_Rn , 0xfd, 0x1f, 1024, "muls.w" , 2, ACC_SWORD }, /* 1100 010 111 */ +{ EA_to_Rn , 0xfd, 0x1f, 1024, "and.b" , 3, ACC_BYTE }, /* 1100 011 000 */ +{ EA_to_Rn , 0xfd, 0x1f, 1024, "and.w" , 3, ACC_WORD }, /* 1100 011 001 */ +{ EA_to_Rn , 0xfd, 0x1f, 1024, "and.l" , 3, ACC_LONG }, /* 1100 011 010 */ +{ EA_to_Rn , 0xfd, 0x1f, 1024, "mulu.w" , 3, ACC_WORD }, /* 1100 011 011 */ +{ Rn_to_EA , 0xfc, 0x03, 1035, "and.b" , 3, ACC_BYTE }, /* 1100 011 100 */ +{ Rn_to_EA , 0xfc, 0x03, 1036, "and.w" , 3, ACC_WORD }, /* 1100 011 101 */ +{ Rn_to_EA , 0xfc, 0x03, 1036, "and.l" , 3, ACC_LONG }, /* 1100 011 110 */ +{ EA_to_Rn , 0xfd, 0x1f, 1024, "muls.w" , 3, ACC_SWORD }, /* 1100 011 111 */ +{ EA_to_Rn , 0xfd, 0x1f, 1024, "and.b" , 4, ACC_BYTE }, /* 1100 100 000 */ +{ EA_to_Rn , 0xfd, 0x1f, 1024, "and.w" , 4, ACC_WORD }, /* 1100 100 001 */ +{ EA_to_Rn , 0xfd, 0x1f, 1024, "and.l" , 4, ACC_LONG }, /* 1100 100 010 */ +{ EA_to_Rn , 0xfd, 0x1f, 1024, "mulu.w" , 4, ACC_WORD }, /* 1100 100 011 */ +{ Rn_to_EA , 0xfc, 0x03, 1035, "and.b" , 4, ACC_BYTE }, /* 1100 100 100 */ +{ Rn_to_EA , 0xfc, 0x03, 1036, "and.w" , 4, ACC_WORD }, /* 1100 100 101 */ +{ Rn_to_EA , 0xfc, 0x03, 1036, "and.l" , 4, ACC_LONG }, /* 1100 100 110 */ +{ EA_to_Rn , 0xfd, 0x1f, 1024, "muls.w" , 4, ACC_SWORD }, /* 1100 100 111 */ +{ EA_to_Rn , 0xfd, 0x1f, 1024, "and.b" , 5, ACC_BYTE }, /* 1100 101 000 */ +{ EA_to_Rn , 0xfd, 0x1f, 1024, "and.w" , 5, ACC_WORD }, /* 1100 101 001 */ +{ EA_to_Rn , 0xfd, 0x1f, 1024, "and.l" , 5, ACC_LONG }, /* 1100 101 010 */ +{ EA_to_Rn , 0xfd, 0x1f, 1024, "mulu.w" , 5, ACC_WORD }, /* 1100 101 011 */ +{ Rn_to_EA , 0xfc, 0x03, 1035, "and.b" , 5, ACC_BYTE }, /* 1100 101 100 */ +{ Rn_to_EA , 0xfc, 0x03, 1036, "and.w" , 5, ACC_WORD }, /* 1100 101 101 */ +{ Rn_to_EA , 0xfc, 0x03, 1036, "and.l" , 5, ACC_LONG }, /* 1100 101 110 */ +{ EA_to_Rn , 0xfd, 0x1f, 1024, "muls.w" , 5, ACC_SWORD }, /* 1100 101 111 */ +{ EA_to_Rn , 0xfd, 0x1f, 1024, "and.b" , 6, ACC_BYTE }, /* 1100 110 000 */ +{ EA_to_Rn , 0xfd, 0x1f, 1024, "and.w" , 6, ACC_WORD }, /* 1100 110 001 */ +{ EA_to_Rn , 0xfd, 0x1f, 1024, "and.l" , 6, ACC_LONG }, /* 1100 110 010 */ +{ EA_to_Rn , 0xfd, 0x1f, 1024, "mulu.w" , 6, ACC_WORD }, /* 1100 110 011 */ +{ Rn_to_EA , 0xfc, 0x03, 1035, "and.b" , 6, ACC_BYTE }, /* 1100 110 100 */ +{ Rn_to_EA , 0xfc, 0x03, 1036, "and.w" , 6, ACC_WORD }, /* 1100 110 101 */ +{ Rn_to_EA , 0xfc, 0x03, 1036, "and.l" , 6, ACC_LONG }, /* 1100 110 110 */ +{ EA_to_Rn , 0xfd, 0x1f, 1024, "muls.w" , 6, ACC_SWORD }, /* 1100 110 111 */ +{ EA_to_Rn , 0xfd, 0x1f, 1024, "and.b" , 7, ACC_BYTE }, /* 1100 111 000 */ +{ EA_to_Rn , 0xfd, 0x1f, 1024, "and.w" , 7, ACC_WORD }, /* 1100 111 001 */ +{ EA_to_Rn , 0xfd, 0x1f, 1024, "and.l" , 7, ACC_LONG }, /* 1100 111 010 */ +{ EA_to_Rn , 0xfd, 0x1f, 1024, "mulu.w" , 7, ACC_WORD }, /* 1100 111 011 */ +{ Rn_to_EA , 0xfc, 0x03, 1035, "and.b" , 7, ACC_BYTE }, /* 1100 111 100 */ +{ Rn_to_EA , 0xfc, 0x03, 1036, "and.w" , 7, ACC_WORD }, /* 1100 111 101 */ +{ Rn_to_EA , 0xfc, 0x03, 1036, "and.l" , 7, ACC_LONG }, /* 1100 111 110 */ +{ EA_to_Rn , 0xfd, 0x1f, 1024, "muls.w" , 7, ACC_SWORD }, /* 1100 111 111 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "add.b" , 0, ACC_BYTE }, /* 1101 000 000 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "add.w" , 0, ACC_WORD }, /* 1101 000 001 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "add.l" , 0, ACC_LONG }, /* 1101 000 010 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "adda.w" , 8, ACC_WORD }, /* 1101 000 011 */ +{ Rn_to_EA , 0xfc, 0x03, 1033, "add.b" , 0, ACC_BYTE }, /* 1101 000 100 */ +{ Rn_to_EA , 0xfc, 0x03, 1038, "add.w" , 0, ACC_WORD }, /* 1101 000 101 */ +{ Rn_to_EA , 0xfc, 0x03, 1039, "add.l" , 0, ACC_LONG }, /* 1101 000 110 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "adda.l" , 8, ACC_LONG }, /* 1101 000 111 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "add.b" , 1, ACC_BYTE }, /* 1101 001 000 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "add.w" , 1, ACC_WORD }, /* 1101 001 001 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "add.l" , 1, ACC_LONG }, /* 1101 001 010 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "adda.w" , 9, ACC_WORD }, /* 1101 001 011 */ +{ Rn_to_EA , 0xfc, 0x03, 1033, "add.b" , 1, ACC_BYTE }, /* 1101 001 100 */ +{ Rn_to_EA , 0xfc, 0x03, 1038, "add.w" , 1, ACC_WORD }, /* 1101 001 101 */ +{ Rn_to_EA , 0xfc, 0x03, 1039, "add.l" , 1, ACC_LONG }, /* 1101 001 110 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "adda.l" , 9, ACC_LONG }, /* 1101 001 111 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "add.b" , 2, ACC_BYTE }, /* 1101 010 000 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "add.w" , 2, ACC_WORD }, /* 1101 010 001 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "add.l" , 2, ACC_LONG }, /* 1101 010 010 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "adda.w" ,10, ACC_WORD }, /* 1101 010 011 */ +{ Rn_to_EA , 0xfc, 0x03, 1033, "add.b" , 2, ACC_BYTE }, /* 1101 010 100 */ +{ Rn_to_EA , 0xfc, 0x03, 1038, "add.w" , 2, ACC_WORD }, /* 1101 010 101 */ +{ Rn_to_EA , 0xfc, 0x03, 1039, "add.l" , 2, ACC_LONG }, /* 1101 010 110 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "adda.l" ,10, ACC_LONG }, /* 1101 010 111 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "add.b" , 3, ACC_BYTE }, /* 1101 011 000 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "add.w" , 3, ACC_WORD }, /* 1101 011 001 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "add.l" , 3, ACC_LONG }, /* 1101 011 010 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "adda.w" ,11, ACC_WORD }, /* 1101 011 011 */ +{ Rn_to_EA , 0xfc, 0x03, 1033, "add.b" , 3, ACC_BYTE }, /* 1101 011 100 */ +{ Rn_to_EA , 0xfc, 0x03, 1038, "add.w" , 3, ACC_WORD }, /* 1101 011 101 */ +{ Rn_to_EA , 0xfc, 0x03, 1039, "add.l" , 3, ACC_LONG }, /* 1101 011 110 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "adda.l" ,11, ACC_LONG }, /* 1101 011 111 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "add.b" , 4, ACC_BYTE }, /* 1101 100 000 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "add.w" , 4, ACC_WORD }, /* 1101 100 001 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "add.l" , 4, ACC_LONG }, /* 1101 100 010 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "adda.w" ,12, ACC_WORD }, /* 1101 100 011 */ +{ Rn_to_EA , 0xfc, 0x03, 1033, "add.b" , 4, ACC_BYTE }, /* 1101 100 100 */ +{ Rn_to_EA , 0xfc, 0x03, 1038, "add.w" , 4, ACC_WORD }, /* 1101 100 101 */ +{ Rn_to_EA , 0xfc, 0x03, 1039, "add.l" , 4, ACC_LONG }, /* 1101 100 110 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "adda.l" ,12, ACC_LONG }, /* 1101 100 111 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "add.b" , 5, ACC_BYTE }, /* 1101 101 000 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "add.w" , 5, ACC_WORD }, /* 1101 101 001 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "add.l" , 5, ACC_LONG }, /* 1101 101 010 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "adda.w" ,13, ACC_WORD }, /* 1101 101 011 */ +{ Rn_to_EA , 0xfc, 0x03, 1033, "add.b" , 5, ACC_BYTE }, /* 1101 101 100 */ +{ Rn_to_EA , 0xfc, 0x03, 1038, "add.w" , 5, ACC_WORD }, /* 1101 101 101 */ +{ Rn_to_EA , 0xfc, 0x03, 1039, "add.l" , 5, ACC_LONG }, /* 1101 101 110 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "adda.l" ,13, ACC_LONG }, /* 1101 101 111 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "add.b" , 6, ACC_BYTE }, /* 1101 110 000 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "add.w" , 6, ACC_WORD }, /* 1101 110 001 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "add.l" , 6, ACC_LONG }, /* 1101 110 010 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "adda.w" ,14, ACC_WORD }, /* 1101 110 011 */ +{ Rn_to_EA , 0xfc, 0x03, 1033, "add.b" , 6, ACC_BYTE }, /* 1101 110 100 */ +{ Rn_to_EA , 0xfc, 0x03, 1038, "add.w" , 6, ACC_WORD }, /* 1101 110 101 */ +{ Rn_to_EA , 0xfc, 0x03, 1039, "add.l" , 6, ACC_LONG }, /* 1101 110 110 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "adda.l" ,14, ACC_LONG }, /* 1101 110 111 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "add.b" , 7, ACC_BYTE }, /* 1101 111 000 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "add.w" , 7, ACC_WORD }, /* 1101 111 001 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "add.l" , 7, ACC_LONG }, /* 1101 111 010 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "adda.w" ,15, ACC_WORD }, /* 1101 111 011 */ +{ Rn_to_EA , 0xfc, 0x03, 1033, "add.b" , 7, ACC_BYTE }, /* 1101 111 100 */ +{ Rn_to_EA , 0xfc, 0x03, 1038, "add.w" , 7, ACC_WORD }, /* 1101 111 101 */ +{ Rn_to_EA , 0xfc, 0x03, 1039, "add.l" , 7, ACC_LONG }, /* 1101 111 110 */ +{ EA_to_Rn , 0xff, 0x1f, 1024, "adda.l" ,15, ACC_LONG }, /* 1101 111 111 */ +{ shiftreg , 0xff, 0xff, 1024, "r.b" , 8, 0 }, /* 1110 000 000 */ +{ shiftreg , 0xff, 0xff, 1024, "r.w" , 8, 0 }, /* 1110 000 001 */ +{ shiftreg , 0xff, 0xff, 1024, "r.l" , 8, 0 }, /* 1110 000 010 */ +{ op1 , 0xfc, 0x03, 1024, "asr.w" , 0, ACC_WORD }, /* 1110 000 011 */ +{ shiftreg , 0xff, 0xff, 1024, "l.b" , 8, 0 }, /* 1110 000 100 */ +{ shiftreg , 0xff, 0xff, 1024, "l.w" , 8, 0 }, /* 1110 000 101 */ +{ shiftreg , 0xff, 0xff, 1024, "l.l" , 8, 0 }, /* 1110 000 110 */ +{ op1 , 0xfc, 0x03, 1024, "asl.w" , 0, ACC_WORD }, /* 1110 000 111 */ +{ shiftreg , 0xff, 0xff, 1024, "r.b" , 1, 0 }, /* 1110 001 000 */ +{ shiftreg , 0xff, 0xff, 1024, "r.w" , 1, 0 }, /* 1110 001 001 */ +{ shiftreg , 0xff, 0xff, 1024, "r.l" , 1, 0 }, /* 1110 001 010 */ +{ op1 , 0xfc, 0x03, 1024, "lsr.w" , 0, ACC_WORD }, /* 1110 001 011 */ +{ shiftreg , 0xff, 0xff, 1024, "l.b" , 1, 0 }, /* 1110 001 100 */ +{ shiftreg , 0xff, 0xff, 1024, "l.w" , 1, 0 }, /* 1110 001 101 */ +{ shiftreg , 0xff, 0xff, 1024, "l.l" , 1, 0 }, /* 1110 001 110 */ +{ op1 , 0xfc, 0x03, 1024, "lsl.w" , 0, ACC_WORD }, /* 1110 001 111 */ +{ shiftreg , 0xff, 0xff, 1024, "r.b" , 2, 0 }, /* 1110 010 000 */ +{ shiftreg , 0xff, 0xff, 1024, "r.w" , 2, 0 }, /* 1110 010 001 */ +{ shiftreg , 0xff, 0xff, 1024, "r.l" , 2, 0 }, /* 1110 010 010 */ +{ op1 , 0xfc, 0x03, 1024, "roxr.w" , 0, ACC_WORD }, /* 1110 010 011 */ +{ shiftreg , 0xff, 0xff, 1024, "l.b" , 2, 0 }, /* 1110 010 100 */ +{ shiftreg , 0xff, 0xff, 1024, "l.w" , 2, 0 }, /* 1110 010 101 */ +{ shiftreg , 0xff, 0xff, 1024, "l.l" , 2, 0 }, /* 1110 010 110 */ +{ op1 , 0xfc, 0x03, 1024, "roxl.w" , 0, ACC_WORD }, /* 1110 010 111 */ +{ shiftreg , 0xff, 0xff, 1024, "r.b" , 3, 0 }, /* 1110 011 000 */ +{ shiftreg , 0xff, 0xff, 1024, "r.w" , 3, 0 }, /* 1110 011 001 */ +{ shiftreg , 0xff, 0xff, 1024, "r.l" , 3, 0 }, /* 1110 011 010 */ +{ op1 , 0xfc, 0x03, 1024, "ror.w" , 0, ACC_WORD }, /* 1110 011 011 */ +{ shiftreg , 0xff, 0xff, 1024, "l.b" , 3, 0 }, /* 1110 011 100 */ +{ shiftreg , 0xff, 0xff, 1024, "l.w" , 3, 0 }, /* 1110 011 101 */ +{ shiftreg , 0xff, 0xff, 1024, "l.l" , 3, 0 }, /* 1110 011 110 */ +{ op1 , 0xfc, 0x03, 1024, "rol.w" , 0, ACC_WORD }, /* 1110 011 111 */ +{ shiftreg , 0xff, 0xff, 1024, "r.b" , 4, 0 }, /* 1110 100 000 */ +{ shiftreg , 0xff, 0xff, 1024, "r.w" , 4, 0 }, /* 1110 100 001 */ +{ shiftreg , 0xff, 0xff, 1024, "r.l" , 4, 0 }, /* 1110 100 010 */ +{ bitfield , 0xe5, 0x0f, 1024, "bftst" , SINGLEOP, 0 }, /* 1110 100 011 */ +{ shiftreg , 0xff, 0xff, 1024, "l.b" , 4, 0 }, /* 1110 100 100 */ +{ shiftreg , 0xff, 0xff, 1024, "l.w" , 4, 0 }, /* 1110 100 101 */ +{ shiftreg , 0xff, 0xff, 1024, "l.l" , 4, 0 }, /* 1110 100 110 */ +{ bitfield , 0xe5, 0x0f, 1024, "bfextu" , DATADEST, 0 }, /* 1110 100 111 */ +{ shiftreg , 0xff, 0xff, 1024, "r.b" , 5, 0 }, /* 1110 101 000 */ +{ shiftreg , 0xff, 0xff, 1024, "r.w" , 5, 0 }, /* 1110 101 001 */ +{ shiftreg , 0xff, 0xff, 1024, "r.l" , 5, 0 }, /* 1110 101 010 */ +{ bitfield , 0xe5, 0x03, 1024, "bfchg" , SINGLEOP, 0 }, /* 1110 101 011 */ +{ shiftreg , 0xff, 0xff, 1024, "l.b" , 5, 0 }, /* 1110 101 100 */ +{ shiftreg , 0xff, 0xff, 1024, "l.w" , 5, 0 }, /* 1110 101 101 */ +{ shiftreg , 0xff, 0xff, 1024, "l.l" , 5, 0 }, /* 1110 101 110 */ +{ bitfield , 0xe5, 0x0f, 1024, "bfexts" , DATADEST, 0 }, /* 1110 101 111 */ +{ shiftreg , 0xff, 0xff, 1024, "r.b" , 6, 0 }, /* 1110 110 000 */ +{ shiftreg , 0xff, 0xff, 1024, "r.w" , 6, 0 }, /* 1110 110 001 */ +{ shiftreg , 0xff, 0xff, 1024, "r.l" , 6, 0 }, /* 1110 110 010 */ +{ bitfield , 0xe5, 0x03, 1024, "bfclr" , SINGLEOP, 0 }, /* 1110 110 011 */ +{ shiftreg , 0xff, 0xff, 1024, "l.b" , 6, 0 }, /* 1110 110 100 */ +{ shiftreg , 0xff, 0xff, 1024, "l.w" , 6, 0 }, /* 1110 110 101 */ +{ shiftreg , 0xff, 0xff, 1024, "l.l" , 6, 0 }, /* 1110 110 110 */ +{ bitfield , 0xe5, 0x0f, 1024, "bfffo" , DATADEST, 0 }, /* 1110 110 111 */ +{ shiftreg , 0xff, 0xff, 1024, "r.b" , 7, 0 }, /* 1110 111 000 */ +{ shiftreg , 0xff, 0xff, 1024, "r.w" , 7, 0 }, /* 1110 111 001 */ +{ shiftreg , 0xff, 0xff, 1024, "r.l" , 7, 0 }, /* 1110 111 010 */ +{ bitfield , 0xe5, 0x03, 1024, "bfset" , SINGLEOP, 0 }, /* 1110 111 011 */ +{ shiftreg , 0xff, 0xff, 1024, "l.b" , 7, 0 }, /* 1110 111 100 */ +{ shiftreg , 0xff, 0xff, 1024, "l.w" , 7, 0 }, /* 1110 111 101 */ +{ shiftreg , 0xff, 0xff, 1024, "l.l" , 7, 0 }, /* 1110 111 110 */ +{ bitfield , 0xe5, 0x03, 1024, "bfins" , DATASRC, 0 }, /* 1110 111 111 */ + +{ mmu30 , 0xe5, 0x03, 1024, 0 , 7, 0 }, /* 1111 000 000 */ +{ invalid , 0xff, 0xff, 1024, 0 , 7, 0 }, /* 1111 000 001 */ +{ invalid , 0xff, 0xff, 1024, 0 , 7, 0 }, /* 1111 000 010 */ +{ invalid , 0xff, 0xff, 1024, 0 , 7, 0 }, /* 1111 000 011 */ +{ invalid , 0xff, 0xff, 1024, 0 , 7, 0 }, /* 1111 000 100 */ +{ invalid , 0xff, 0xff, 1024, 0 , 7, 0 }, /* 1111 000 101 */ +{ invalid , 0xff, 0xff, 1024, 0 , 7, 0 }, /* 1111 000 110 */ +{ invalid , 0xff, 0xff, 1024, 0 , 7, 0 }, /* 1111 000 111 */ +/* FPU opcode encodings */ +{ fpu , 0xff, 0xff, 1024, 0 , 1, 0 }, /* 1111 001 000 */ +{ fscc , 0xfd, 0x03, 1047, "fs" , 1, 0 }, /* 1111 001 001 */ +{ fbranch , 0xff, 0x00, 1024, "fb" , 0, ACC_CODE }, /* 1111 001 010 */ +{ fbranch , 0xff, 0x00, 1024, "fb" , 1, ACC_CODE }, /* 1111 001 011 */ +{ op1 , 0xf4, 0x03, 1024, "fsave" , 0, ACC_LONG }, /* 1111 001 100 */ +{ op1 , 0xec, 0x0f, 1024, "frestore", 0, ACC_LONG }, /* 1111 001 101 */ +{ invalid , 0xff, 0xff, 1024, 0 , 0, 0 }, /* 1111 001 110 */ +{ invalid , 0xff, 0xff, 1024, 0 , 0, 0 }, /* 1111 001 111 */ + +/* Opcodes for user-definable coprocessors */ +{ cache , 0xee, 0xff, 1024, 0 , 0, 0 }, /* 1111 010 000 */ +{ cache , 0xee, 0xff, 1024, 0 , 1, 0 }, /* 1111 010 001 */ +{ cache , 0xee, 0xff, 1024, 0 , 2, 0 }, /* 1111 010 010 */ +{ cache , 0xee, 0xff, 1024, 0 , 3, 0 }, /* 1111 010 011 */ +{ pflush40 , 0x0f, 0xff, 1024, "pflush" , 0, 0 }, /* 1111 010 100 */ +{ ptest40 , 0x22, 0xff, 1024, "ptest" , 7, 0 }, /* 1111 010 101 */ +{ plpa60 , 0x02, 0x00, 1024, "plpaw" , 7, 0 }, /* 1111 010 110 */ +{ plpa60 , 0x02, 0x00, 1024, "plpar" , 7, 0 }, /* 1111 010 111 */ +{ move16 , 0x1f, 0xff, 1024, "move16" , 7, 0 }, /* 1111 011 000 */ +{ invalid , 0xff, 0xff, 1024, 0 , 7, 0 }, /* 1111 011 001 */ +{ invalid , 0xff, 0xff, 1024, 0 , 7, 0 }, /* 1111 011 010 */ +{ invalid , 0xff, 0xff, 1024, 0 , 7, 0 }, /* 1111 011 011 */ +{ invalid , 0xff, 0xff, 1024, 0 , 7, 0 }, /* 1111 011 100 */ +{ invalid , 0xff, 0xff, 1024, 0 , 7, 0 }, /* 1111 011 101 */ +{ invalid , 0xff, 0xff, 1024, 0 , 7, 0 }, /* 1111 011 110 */ +{ invalid , 0xff, 0xff, 1024, 0 , 7, 0 }, /* 1111 011 111 */ +{ invalid , 0xff, 0xff, 1024, 0 , 7, 0 }, /* 1111 100 000 */ +{ invalid , 0xff, 0xff, 1024, 0 , 7, 0 }, /* 1111 100 001 */ +{ invalid , 0xff, 0xff, 1024, 0 , 7, 0 }, /* 1111 100 010 */ +{ invalid , 0xff, 0xff, 1024, 0 , 7, 0 }, /* 1111 100 011 */ +{ invalid , 0xff, 0xff, 1024, 0 , 7, 0 }, /* 1111 100 100 */ +{ invalid , 0xff, 0xff, 1024, 0 , 7, 0 }, /* 1111 100 101 */ +{ invalid , 0xff, 0xff, 1024, 0 , 7, 0 }, /* 1111 100 110 */ +{ invalid , 0xff, 0xff, 1024, 0 , 7, 0 }, /* 1111 100 111 */ +{ invalid , 0xff, 0xff, 1024, 0 , 7, 0 }, /* 1111 101 000 */ +{ invalid , 0xff, 0xff, 1024, 0 , 7, 0 }, /* 1111 101 001 */ +{ invalid , 0xff, 0xff, 1024, 0 , 7, 0 }, /* 1111 101 010 */ +{ invalid , 0xff, 0xff, 1024, 0 , 7, 0 }, /* 1111 101 011 */ +{ invalid , 0xff, 0xff, 1024, 0 , 7, 0 }, /* 1111 101 100 */ +{ invalid , 0xff, 0xff, 1024, 0 , 7, 0 }, /* 1111 101 101 */ +{ invalid , 0xff, 0xff, 1024, 0 , 7, 0 }, /* 1111 101 110 */ +{ invalid , 0xff, 0xff, 1024, 0 , 7, 0 }, /* 1111 101 111 */ +{ invalid , 0xff, 0xff, 1024, 0 , 7, 0 }, /* 1111 110 000 */ +{ invalid , 0xff, 0xff, 1024, 0 , 7, 0 }, /* 1111 110 001 */ +{ invalid , 0xff, 0xff, 1024, 0 , 7, 0 }, /* 1111 110 010 */ +{ invalid , 0xff, 0xff, 1024, 0 , 7, 0 }, /* 1111 110 011 */ +{ invalid , 0xff, 0xff, 1024, 0 , 7, 0 }, /* 1111 110 100 */ +{ invalid , 0xff, 0xff, 1024, 0 , 7, 0 }, /* 1111 110 101 */ +{ invalid , 0xff, 0xff, 1024, 0 , 7, 0 }, /* 1111 110 110 */ +{ invalid , 0xff, 0xff, 1024, 0 , 7, 0 }, /* 1111 110 111 */ +{ invalid , 0xff, 0xff, 1024, 0 , 7, 0 }, /* 1111 111 000 */ +{ invalid , 0xff, 0xff, 1024, 0 , 7, 0 }, /* 1111 111 001 */ +{ invalid , 0xff, 0xff, 1024, 0 , 7, 0 }, /* 1111 111 010 */ +{ invalid , 0xff, 0xff, 1024, 0 , 7, 0 }, /* 1111 111 011 */ +{ invalid , 0xff, 0xff, 1024, 0 , 7, 0 }, /* 1111 111 100 */ +{ invalid , 0xff, 0xff, 1024, 0 , 7, 0 }, /* 1111 111 101 */ +{ invalid , 0xff, 0xff, 1024, 0 , 7, 0 }, /* 1111 111 110 */ +{ invalid , 0xff, 0xff, 1024, 0 , 7, 0 }, /* 1111 111 111 */ + +/* Here are the chained routines for handling doubly-defined opcodes */ + +{ invalid , 0xff, 0xff, 0, 0 , 0, 0 }, /* 1024 */ +{ illegal , 0x80, 0x10, 1024, "illegal" , 0, 0 }, /* 1025 */ +{ srccr , 0x80, 0x10, 1024, 0 , 0, 0 }, /* 1026 */ +{ op1_end , 0x03, 0x00, 1024, "rtm" , 0, 0 }, /* 1027 */ +{ op2_bcdx , 0x03, 0x00, 1024, "unpk" , ADJUST, 0 }, /* 1028 */ +{ op1 , 0x01, 0x00, 1049, "swap" , 0, ACC_LONG }, /* 1029 */ +{ op1 , 0x01, 0x00, 1024, "ext.w" , 0, ACC_WORD }, /* 1030 */ +{ op2_bcdx , 0x03, 0x00, 1024, "sbcd" , NO_ADJ, 0 }, /* 1031 */ +{ op2_bcdx , 0x03, 0x00, 1024, "pack" , ADJUST, 0 }, /* 1032 */ +{ op2_bcdx , 0x03, 0x00, 1024, "addx.b" , NO_ADJ, 0 }, /* 1033 */ +{ cmpm , 0x02, 0xff, 1024, "cmpm.b" , 0, 0 }, /* 1034 */ +{ op2_bcdx , 0x03, 0x00, 1024, "abcd.b" , NO_ADJ, 0 }, /* 1035 */ +{ exg , 0x03, 0x00, 1024, "exg" , 0, 0 }, /* 1036 */ +{ movep , 0x02, 0x00, 1024, "movep" , 0, 0 }, /* 1037 */ +{ op2_bcdx , 0x03, 0x00, 1024, "addx.w" , NO_ADJ, 0 }, /* 1038 */ +{ op2_bcdx , 0x03, 0x00, 1024, "addx.l" , NO_ADJ, 0 }, /* 1039 */ +{ cas2 , 0x80, 0x10, 1024, "cas2.b" , 0, ACC_BYTE }, /* 1040 */ +{ cas2 , 0x80, 0x10, 1024, "cas2.w" , 0, ACC_WORD }, /* 1041 */ +{ cas2 , 0x80, 0x10, 1024, "cas2.l" , 0, ACC_LONG }, /* 1042 */ +{ cmpm , 0x02, 0xff, 1024, "cmpm.w" , 0, 0 }, /* 1043 */ +{ cmpm , 0x02, 0xff, 1024, "cmpm.l" , 0, 0 }, /* 1044 */ +{ trapcc , 0x80, 0x1c, 1024, "trap" , 0, 0 }, /* 1045 */ +{ scc , 0xfd, 0x03, 1045, "s" , 0, ACC_BYTE }, /* 1046 */ +{ fdbranch , 0x02, 0x00, 1048, "fdb" , 0, 0 }, /* 1047 */ +{ ftrapcc , 0x80, 0x1c, 1024, "ftrap" , 0, 0 }, /* 1048 */ +{ bkpt , 0x02, 0xff, 1024, "bkpt" , 0, 0 }, /* 1049 */ +{ op1 , 0x01, 0x00, 1024, "ext.l" , 0, ACC_LONG }, /* 1050 */ +{ op1 , 0x01, 0x00, 1024, "extb.l" , 0, ACC_LONG }, /* 1051 */ +{ op2_bcdx , 0x03, 0x00, 1024, "subx.b" , NO_ADJ, 0 }, /* 1052 */ +{ op2_bcdx , 0x03, 0x00, 1024, "subx.w" , NO_ADJ, 0 }, /* 1053 */ +{ op2_bcdx , 0x03, 0x00, 1024, "subx.l" , NO_ADJ, 0 }, /* 1054 */ +{ link_l , 0x02, 0x00, 1024, "link.l" , 0, 0 }, /* 1055 */ +/* ColdFire chains */ +{ op1 , 0x03, 0x00, 1024, "bitrev" , 0, ACC_LONG }, /* 1056 */ +{ op1 , 0x03, 0x00, 1024, "byterev" , 0, ACC_LONG }, /* 1057 */ +{ op1 , 0x03, 0x00, 1024, "ff1" , 0, ACC_LONG }, /* 1058 */ +{ op1 , 0x03, 0x00, 1024, "sats" , 0, ACC_SLONG } /* 1059 */ +}; diff --git a/cputest/adis/opcodes_fpu.c b/cputest/adis/opcodes_fpu.c new file mode 100644 index 00000000..f6881017 --- /dev/null +++ b/cputest/adis/opcodes_fpu.c @@ -0,0 +1,211 @@ +/* + * Change history + * $Log: fpu_opcodes.c,v $ + * Revision 3.0 93/09/24 17:53:57 Martin_Apel + * New feature: Added extra 68040 FPU opcodes + * + * Revision 2.1 93/07/18 22:55:54 Martin_Apel + * *** empty log message *** + * + * Revision 2.0 93/07/01 11:53:57 Martin_Apel + * *** empty log message *** + * + * Revision 1.6 93/06/16 20:27:22 Martin_Apel + * Minor mod.: Removed #ifdef FPU_VERSION and #ifdef MACHINE68020 + * + * Revision 1.5 93/06/03 20:27:05 Martin_Apel + * + * + */ + +#include "defs.h" + +/* static char rcsid [] = "$Id: fpu_opcodes.c,v 3.0 93/09/24 17:53:57 Martin_Apel Exp $"; */ + +struct opcode_sub_entry fpu_opcode_table [] = +{ +/* *handler, *mnemonic, param, access */ + +{ std_fpu , "fmove" , 0, 0 }, /* 000 0000 */ +{ std_fpu , "fint" , SNG_ALL, 0 }, /* 000 0001 */ +{ std_fpu , "fsinh" , SNG_ALL, 0 }, /* 000 0010 */ +{ std_fpu , "fintrz" , SNG_ALL, 0 }, /* 000 0011 */ +{ std_fpu , "fsqrt" , SNG_ALL, 0 }, /* 000 0100 */ +{ invalid2 , 0 , 0, 0 }, /* 000 0101 */ +{ std_fpu , "flognp1", SNG_ALL, 0 }, /* 000 0110 */ +{ invalid2 , 0 , 0, 0 }, /* 000 0111 */ +{ std_fpu , "fetoxm1", SNG_ALL, 0 }, /* 000 1000 */ +{ std_fpu , "ftanh" , SNG_ALL, 0 }, /* 000 1001 */ +{ std_fpu , "fatan" , SNG_ALL, 0 }, /* 000 1010 */ +{ invalid2 , 0 , 0, 0 }, /* 000 1011 */ +{ std_fpu , "fasin" , SNG_ALL, 0 }, /* 000 1100 */ +{ std_fpu , "fatanh" , SNG_ALL, 0 }, /* 000 1101 */ +{ std_fpu , "fsin" , SNG_ALL, 0 }, /* 000 1110 */ +{ std_fpu , "ftan" , SNG_ALL, 0 }, /* 000 1111 */ +{ std_fpu , "fetox" , SNG_ALL, 0 }, /* 001 0000 */ +{ std_fpu , "ftwotox", SNG_ALL, 0 }, /* 001 0001 */ +{ std_fpu , "ftentox", SNG_ALL, 0 }, /* 001 0010 */ +{ invalid2 , 0 , 0, 0 }, /* 001 0011 */ +{ std_fpu , "flogn" , SNG_ALL, 0 }, /* 001 0100 */ +{ std_fpu , "flog10" , SNG_ALL, 0 }, /* 001 0101 */ +{ std_fpu , "flog2" , SNG_ALL, 0 }, /* 001 0110 */ +{ invalid2 , 0 , 0, 0 }, /* 001 0111 */ +{ std_fpu , "fabs" , SNG_ALL, 0 }, /* 001 1000 */ +{ std_fpu , "fcosh" , SNG_ALL, 0 }, /* 001 1001 */ +{ std_fpu , "fneg" , SNG_ALL, 0 }, /* 001 1010 */ +{ invalid2 , 0 , 0, 0 }, /* 001 1011 */ +{ std_fpu , "facos" , SNG_ALL, 0 }, /* 001 1100 */ +{ std_fpu , "fcos" , SNG_ALL, 0 }, /* 001 1101 */ +{ std_fpu , "fgetexp", SNG_ALL, 0 }, /* 001 1110 */ +{ std_fpu , "fgetman", SNG_ALL, 0 }, /* 001 1111 */ +{ std_fpu , "fdiv" , 0, 0 }, /* 010 0000 */ +{ std_fpu , "fmod" , 0, 0 }, /* 010 0001 */ +{ std_fpu , "fadd" , 0, 0 }, /* 010 0010 */ +{ std_fpu , "fmul" , 0, 0 }, /* 010 0011 */ +{ std_fpu , "fsgldiv", 0, 0 }, /* 010 0100 */ +{ std_fpu , "frem" , 0, 0 }, /* 010 0101 */ +{ std_fpu , "fscale" , 0, 0 }, /* 010 0110 */ +{ std_fpu , "fsglmul", 0, 0 }, /* 010 0111 */ +{ std_fpu , "fsub" , 0, 0 }, /* 010 1000 */ +{ invalid2 , 0 , 0, 0 }, /* 010 1001 */ +{ invalid2 , 0 , 0, 0 }, /* 010 1010 */ +{ invalid2 , 0 , 0, 0 }, /* 010 1011 */ +{ invalid2 , 0 , 0, 0 }, /* 010 1100 */ +{ invalid2 , 0 , 0, 0 }, /* 010 1101 */ +{ invalid2 , 0 , 0, 0 }, /* 010 1110 */ +{ invalid2 , 0 , 0, 0 }, /* 010 1111 */ +{ fsincos , "fsincos", 0, 0 }, /* 011 0000 */ +{ fsincos , "fsincos", 1, 0 }, /* 011 0001 */ +{ fsincos , "fsincos", 2, 0 }, /* 011 0010 */ +{ fsincos , "fsincos", 3, 0 }, /* 011 0011 */ +{ fsincos , "fsincos", 4, 0 }, /* 011 0100 */ +{ fsincos , "fsincos", 5, 0 }, /* 011 0101 */ +{ fsincos , "fsincos", 6, 0 }, /* 011 0110 */ +{ fsincos , "fsincos", 7, 0 }, /* 011 0111 */ +{ std_fpu , "fcmp" , 0, 0 }, /* 011 1000 */ +{ invalid2 , 0 , 0, 0 }, /* 011 1001 */ +{ ftst , "ftst" , 0, 0 }, /* 011 1010 */ +{ invalid2 , 0 , 0, 0 }, /* 011 1011 */ +{ invalid2 , 0 , 0, 0 }, /* 011 1100 */ +{ invalid2 , 0 , 0, 0 }, /* 011 1101 */ +{ invalid2 , 0 , 0, 0 }, /* 011 1110 */ +{ invalid2 , 0 , 0, 0 }, /* 011 1111 */ + +{ std_fpu , "fsmove" , 0, 0 }, /* 100 0000 */ +{ std_fpu , "fssqrt" , SNG_ALL, 0 }, /* 100 0001 */ +{ invalid2 , 0 , 0, 0 }, /* 100 0010 */ +{ invalid2 , 0 , 0, 0 }, /* 100 0011 */ +{ std_fpu , "fdmove" , 0, 0 }, /* 100 0100 */ +{ std_fpu , "fdsqrt" , SNG_ALL, 0 }, /* 100 0101 */ +{ invalid2 , 0 , 0, 0 }, /* 100 0110 */ +{ invalid2 , 0 , 0, 0 }, /* 100 0111 */ +{ invalid2 , 0 , 0, 0 }, /* 100 1000 */ +{ invalid2 , 0 , 0, 0 }, /* 100 1001 */ +{ invalid2 , 0 , 0, 0 }, /* 100 1010 */ +{ invalid2 , 0 , 0, 0 }, /* 100 1011 */ +{ invalid2 , 0 , 0, 0 }, /* 100 1100 */ +{ invalid2 , 0 , 0, 0 }, /* 100 1101 */ +{ invalid2 , 0 , 0, 0 }, /* 100 1110 */ +{ invalid2 , 0 , 0, 0 }, /* 100 1111 */ +{ invalid2 , 0 , 0, 0 }, /* 101 0000 */ +{ invalid2 , 0 , 0, 0 }, /* 101 0001 */ +{ invalid2 , 0 , 0, 0 }, /* 101 0010 */ +{ invalid2 , 0 , 0, 0 }, /* 101 0011 */ +{ invalid2 , 0 , 0, 0 }, /* 101 0100 */ +{ invalid2 , 0 , 0, 0 }, /* 101 0101 */ +{ invalid2 , 0 , 0, 0 }, /* 101 0110 */ +{ invalid2 , 0 , 0, 0 }, /* 101 0111 */ +{ std_fpu , "fsabs" , SNG_ALL, 0 }, /* 101 1000 */ +{ invalid2 , 0 , 0, 0 }, /* 101 1001 */ +{ std_fpu , "fsneg" , SNG_ALL, 0 }, /* 101 1010 */ +{ invalid2 , 0 , 0, 0 }, /* 101 1011 */ +{ std_fpu , "fdabs" , SNG_ALL, 0 }, /* 101 1100 */ +{ invalid2 , 0 , 0, 0 }, /* 101 1101 */ +{ std_fpu , "fdneg" , SNG_ALL, 0 }, /* 101 1110 */ +{ invalid2 , 0 , 0, 0 }, /* 101 1111 */ +{ std_fpu , "fsdiv" , 0, 0 }, /* 110 0000 */ +{ invalid2 , 0 , 0, 0 }, /* 110 0001 */ +{ std_fpu , "fsadd" , 0, 0 }, /* 110 0010 */ +{ std_fpu , "fsmul" , 0, 0 }, /* 110 0011 */ +{ std_fpu , "fddiv" , 0, 0 }, /* 110 0100 */ +{ invalid2 , 0 , 0, 0 }, /* 110 0101 */ +{ std_fpu , "fdadd" , 0, 0 }, /* 110 0110 */ +{ std_fpu , "fdmul" , 0, 0 }, /* 110 0111 */ +{ std_fpu , "fssub" , 0, 0 }, /* 110 1000 */ +{ invalid2 , 0 , 0, 0 }, /* 110 1001 */ +{ invalid2 , 0 , 0, 0 }, /* 110 1010 */ +{ invalid2 , 0 , 0, 0 }, /* 110 1011 */ +{ std_fpu , "fdsub" , 0, 0 }, /* 110 1100 */ +{ invalid2 , 0 , 0, 0 }, /* 110 1101 */ +{ invalid2 , 0 , 0, 0 }, /* 110 1110 */ +{ invalid2 , 0 , 0, 0 }, /* 110 1111 */ +{ invalid2 , 0 , 0, 0 }, /* 111 0000 */ +{ invalid2 , 0 , 0, 0 }, /* 111 0001 */ +{ invalid2 , 0 , 0, 0 }, /* 111 0010 */ +{ invalid2 , 0 , 0, 0 }, /* 111 0011 */ +{ invalid2 , 0 , 0, 0 }, /* 111 0100 */ +{ invalid2 , 0 , 0, 0 }, /* 111 0101 */ +{ invalid2 , 0 , 0, 0 }, /* 111 0110 */ +{ invalid2 , 0 , 0, 0 }, /* 111 0111 */ +{ invalid2 , 0 , 0, 0 }, /* 111 1000 */ +{ invalid2 , 0 , 0, 0 }, /* 111 1001 */ +{ invalid2 , 0 , 0, 0 }, /* 111 1010 */ +{ invalid2 , 0 , 0, 0 }, /* 111 1011 */ +{ invalid2 , 0 , 0, 0 }, /* 111 1100 */ +{ invalid2 , 0 , 0, 0 }, /* 111 1101 */ +{ invalid2 , 0 , 0, 0 }, /* 111 1110 */ +{ invalid2 , 0 , 0, 0 } /* 111 1111 */ +}; + +char *xfer_size [] = { ".l", + ".s", + ".x", + ".p", + ".w", + ".d", + ".b", + ".p", }; + +UWORD sizes [] = { ACC_LONG | ACC_DATA, + ACC_LONG | ACC_DATA, + ACC_EXTEND | ACC_DATA, + ACC_EXTEND | ACC_DATA, + ACC_WORD | ACC_DATA, + ACC_DOUBLE | ACC_DATA, + ACC_BYTE | ACC_DATA, + ACC_EXTEND | ACC_DATA }; + +char *fpu_conditions [] = { + "f", + "eq", + "ogt", + "oge", + "olt", + "ole", + "ogl", + "or", + "un", /* 8 */ + "ueq", + "ugt", + "uge", + "ult", + "ule", + "ne", + "t", + "sf", /* 16 */ + "seq", + "gt", + "ge", + "lt", + "le", + "gl", + "gle", + "ngle", /* 24 */ + "ngl", + "nle", + "nlt", + "nge", + "ngt", + "sne", + "st" +}; diff --git a/cputest/adis/opcodes_mmu.c b/cputest/adis/opcodes_mmu.c new file mode 100644 index 00000000..7b330340 --- /dev/null +++ b/cputest/adis/opcodes_mmu.c @@ -0,0 +1,63 @@ +/* + * Change history + * $Log: mmu_opcodes.c,v $ + * Revision 3.0 93/09/24 17:54:10 Martin_Apel + * New feature: Added extra 68040 FPU opcodes + * + * Revision 2.2 93/07/18 22:56:14 Martin_Apel + * *** empty log message *** + * + * Revision 2.1 93/07/08 20:47:50 Martin_Apel + * Bug fix: Replaced illegal with pmove30 + * + * Revision 2.0 93/07/01 11:54:18 Martin_Apel + * *** empty log message *** + * + * Revision 1.1 93/06/19 12:11:42 Martin_Apel + * Initial revision + * + */ + +#include "defs.h" + +/* static char rcsid [] = "$Id: mmu_opcodes.c,v 3.0 93/09/24 17:54:10 Martin_Apel Exp $"; */ + +/* Table for the bits 14 to 10 of the second word of mmu opcodes */ + +struct opcode_sub_entry mmu_opcode_table [] = +{ +/* *handler, *mnemonic, param, access */ + +{ invalid2 , 0 , 0, 0 }, /* 0 0000 */ +{ invalid2 , 0 , 0, 0 }, /* 0 0001 */ +{ pmove30 , "pmove" , TT0, 0 }, /* 0 0010 */ +{ pmove30 , "pmove" , TT1, 0 }, /* 0 0011 */ +{ invalid2 , 0 , 0, 0 }, /* 0 0100 */ +{ invalid2 , 0 , 0, 0 }, /* 0 0101 */ +{ invalid2 , 0 , 0, 0 }, /* 0 0110 */ +{ invalid2 , 0 , 0, 0 }, /* 0 0111 */ +{ pfl_or_ld, "pflush" , 0, 0 }, /* 0 1000 */ +{ pflush30 , "pflush" , 1, 0 }, /* 0 1001 */ +{ pflush30 , "pflush" , 2, 0 }, /* 0 1010 */ +{ pflush30 , "pflush" , 3, 0 }, /* 0 1011 */ +{ pflush30 , "pflush" , 4, 0 }, /* 0 1100 */ +{ pflush30 , "pflush" , 5, 0 }, /* 0 1101 */ +{ pflush30 , "pflush" , 6, 0 }, /* 0 1110 */ +{ pflush30 , "pflush" , 7, 0 }, /* 0 1111 */ +{ pmove30 , "pmove" , TC, 0 }, /* 1 0000 */ +{ invalid2 , 0 , 0, 0 }, /* 1 0001 */ +{ pmove30 , "pmove" , SRP, 0 }, /* 1 0010 */ +{ pmove30 , "pmove" , CRP, 0 }, /* 1 0011 */ +{ invalid2 , 0 , 0, 0 }, /* 1 0100 */ +{ invalid2 , 0 , 0, 0 }, /* 1 0101 */ +{ invalid2 , 0 , 0, 0 }, /* 1 0110 */ +{ invalid2 , 0 , 0, 0 }, /* 1 0111 */ +{ pmove30 , "pmove" , MMUSR, 0 }, /* 1 1000 */ +{ invalid2 , 0 , 0, 0 }, /* 1 1001 */ +{ invalid2 , 0 , 0, 0 }, /* 1 1010 */ +{ invalid2 , 0 , 0, 0 }, /* 1 1011 */ +{ invalid2 , 0 , 0, 0 }, /* 1 1100 */ +{ invalid2 , 0 , 0, 0 }, /* 1 1101 */ +{ invalid2 , 0 , 0, 0 }, /* 1 1110 */ +{ invalid2 , 0 , 0, 0 } /* 1 1111 */ +}; diff --git a/cputest/adis/string_recog.h b/cputest/adis/string_recog.h new file mode 100644 index 00000000..87d414ab --- /dev/null +++ b/cputest/adis/string_recog.h @@ -0,0 +1,309 @@ +/* + * Change history + * $Log: string_recog.h,v $ + * Revision 3.0 93/09/24 17:54:41 Martin_Apel + * New feature: Added extra 68040 FPU opcodes + * + * Revision 2.1 93/07/18 22:57:12 Martin_Apel + * *** empty log message *** + * + * Revision 2.0 93/07/01 11:55:11 Martin_Apel + * *** empty log message *** + * + * Revision 1.4 93/06/03 20:31:25 Martin_Apel + * + * + */ + +/* $Id: string_recog.h,v 3.0 93/09/24 17:54:41 Martin_Apel Exp $ */ + +#define C_PRINT 0x01 /* printable character including german umlauts */ +#define C_NAME 0x02 /* character is valid in a C variable name */ +#define C_NORM 0x04 /* common/normal character */ +#define C_NUM 0x08 /* character is a decimal number 0-9 */ +#define C_HEX 0x10 /* character is a hexadecimal number 0-9,A-F,a-f */ +#define C_PATH 0x20 /* character is valid in a path and file name */ +#define C_ALL 0x80 /* all valid printable or control characters */ + +#define IS_PRINTABLE(c) (c_table[c] & C_PRINT) +#define IS_NAME(c) (c_table[c] & C_NAME) +#define IS_COMMON(c) (c_table[c] & C_NORM) +#define IS_VALID(c) (c_table[c] & C_ALL) +#define IS_NUM(c) (c_table[c] & C_NUM) +#define IS_HEX(c) (c_table[c] & C_HEX) +#define IS_PATH(c) (c_table[c] & C_PATH) + +static const UBYTE c_table [256] = + { + 0, /* $0 EOS */ + 0, /* $1 */ + 0, /* $2 */ + 0, /* $3 */ + 0, /* $4 */ + 0, /* $5 */ + 0, /* $6 */ + C_ALL, /* $7 bell */ + C_ALL, /* $8 BS */ + C_ALL | C_NORM, /* $9 TAB */ + C_ALL | C_NORM, /* $A LF */ + 0, /* $B */ + C_ALL, /* $C FF */ + C_ALL | C_NORM, /* $D CR */ + 0, /* $E */ + 0, /* $F */ + + 0, /* $10 */ + 0, /* $11 */ + 0, /* $12 */ + 0, /* $13 */ + 0, /* $14 */ + 0, /* $15 */ + 0, /* $16 */ + 0, /* $17 */ + 0, /* $18 */ + 0, /* $19 */ + 0, /* $1A */ + C_ALL, /* $1B ESC */ + 0, /* $1C */ + 0, /* $1D */ + 0, /* $1E */ + 0, /* $1F */ + + C_ALL | C_PRINT | C_NORM | C_PATH, /* $20 SPACE */ + C_ALL | C_PRINT | C_NORM | C_PATH, /* $21 ! */ + C_ALL | C_PRINT | C_NORM, /* $22 " */ + C_ALL | C_PRINT | C_NORM, /* $23 # */ + C_ALL | C_PRINT | C_NORM, /* $24 $ */ + C_ALL | C_PRINT | C_NORM, /* $25 % */ + C_ALL | C_PRINT | C_NORM | C_PATH, /* $26 & */ + C_ALL | C_PRINT | C_NORM | C_PATH, /* $27 ' */ + C_ALL | C_PRINT | C_NORM, /* $28 ( */ + C_ALL | C_PRINT | C_NORM, /* $29 ) */ + C_ALL | C_PRINT | C_NORM, /* $2A * */ + C_ALL | C_PRINT | C_NORM | C_PATH, /* $2B + */ + C_ALL | C_PRINT | C_NORM | C_PATH, /* $2C , */ + C_ALL | C_PRINT | C_NORM | C_PATH, /* $2D - */ + C_ALL | C_PRINT | C_NORM | C_PATH, /* $2E . */ + C_ALL | C_PRINT | C_NORM | C_PATH, /* $2F / */ + + C_ALL | C_PRINT | C_NAME | C_NORM | C_NUM | C_HEX | C_PATH, /* $30 0 */ + C_ALL | C_PRINT | C_NAME | C_NORM | C_NUM | C_HEX | C_PATH, /* $31 1 */ + C_ALL | C_PRINT | C_NAME | C_NORM | C_NUM | C_HEX | C_PATH, /* $32 2 */ + C_ALL | C_PRINT | C_NAME | C_NORM | C_NUM | C_HEX | C_PATH, /* $33 3 */ + C_ALL | C_PRINT | C_NAME | C_NORM | C_NUM | C_HEX | C_PATH, /* $34 4 */ + C_ALL | C_PRINT | C_NAME | C_NORM | C_NUM | C_HEX | C_PATH, /* $35 5 */ + C_ALL | C_PRINT | C_NAME | C_NORM | C_NUM | C_HEX | C_PATH, /* $36 6 */ + C_ALL | C_PRINT | C_NAME | C_NORM | C_NUM | C_HEX | C_PATH, /* $37 7 */ + C_ALL | C_PRINT | C_NAME | C_NORM | C_NUM | C_HEX | C_PATH, /* $38 8 */ + C_ALL | C_PRINT | C_NAME | C_NORM | C_NUM | C_HEX | C_PATH, /* $39 9 */ + C_ALL | C_PRINT | C_NORM | C_PATH, /* $3A : */ + C_ALL | C_PRINT | C_NORM, /* $3B ; */ + C_ALL | C_PRINT | C_NORM, /* $3C < */ + C_ALL | C_PRINT | C_NORM | C_PATH, /* $3D = */ + C_ALL | C_PRINT | C_NORM, /* $3E > */ + C_ALL | C_PRINT | C_NORM, /* $3F ? */ + + C_ALL | C_PRINT | C_NORM | C_PATH, /* $40 @ */ + C_ALL | C_PRINT | C_NAME | C_NORM | C_HEX | C_PATH, /* $41 A */ + C_ALL | C_PRINT | C_NAME | C_NORM | C_HEX | C_PATH, /* $42 B */ + C_ALL | C_PRINT | C_NAME | C_NORM | C_HEX | C_PATH, /* $43 C */ + C_ALL | C_PRINT | C_NAME | C_NORM | C_HEX | C_PATH, /* $44 D */ + C_ALL | C_PRINT | C_NAME | C_NORM | C_HEX | C_PATH, /* $45 E */ + C_ALL | C_PRINT | C_NAME | C_NORM | C_HEX | C_PATH, /* $46 F */ + C_ALL | C_PRINT | C_NAME | C_NORM | C_PATH, /* $47 G */ + C_ALL | C_PRINT | C_NAME | C_NORM | C_PATH, /* $48 H */ + C_ALL | C_PRINT | C_NAME | C_NORM | C_PATH, /* $49 I */ + C_ALL | C_PRINT | C_NAME | C_NORM | C_PATH, /* $4A J */ + C_ALL | C_PRINT | C_NAME | C_NORM | C_PATH, /* $4B K */ + C_ALL | C_PRINT | C_NAME | C_NORM | C_PATH, /* $4C L */ + C_ALL | C_PRINT | C_NAME | C_NORM | C_PATH, /* $4D M */ + C_ALL | C_PRINT | C_NAME | C_NORM | C_PATH, /* $4E N */ + C_ALL | C_PRINT | C_NAME | C_NORM | C_PATH, /* $4F O */ + + C_ALL | C_PRINT | C_NAME | C_NORM | C_PATH, /* $50 P */ + C_ALL | C_PRINT | C_NAME | C_NORM | C_PATH, /* $51 Q */ + C_ALL | C_PRINT | C_NAME | C_NORM | C_PATH, /* $52 R */ + C_ALL | C_PRINT | C_NAME | C_NORM | C_PATH, /* $53 S */ + C_ALL | C_PRINT | C_NAME | C_NORM | C_PATH, /* $54 T */ + C_ALL | C_PRINT | C_NAME | C_NORM | C_PATH, /* $55 U */ + C_ALL | C_PRINT | C_NAME | C_NORM | C_PATH, /* $56 V */ + C_ALL | C_PRINT | C_NAME | C_NORM | C_PATH, /* $57 W */ + C_ALL | C_PRINT | C_NAME | C_NORM | C_PATH, /* $58 X */ + C_ALL | C_PRINT | C_NAME | C_NORM | C_PATH, /* $59 Y */ + C_ALL | C_PRINT | C_NAME | C_NORM | C_PATH, /* $5A Z */ + C_ALL | C_PRINT | C_NORM, /* $5B [ */ + C_ALL | C_PRINT | C_NORM, /* $5C \ */ + C_ALL | C_PRINT | C_NORM, /* $5D ] */ + C_ALL | C_PRINT | C_NORM | C_PATH, /* $5E ^ */ + C_ALL | C_PRINT | C_NAME | C_NORM | C_PATH, /* $5F _ */ + + C_ALL | C_PRINT | C_NORM, /* $60 ` */ + C_ALL | C_PRINT | C_NAME | C_NORM | C_HEX | C_PATH, /* $61 a */ + C_ALL | C_PRINT | C_NAME | C_NORM | C_HEX | C_PATH, /* $62 b */ + C_ALL | C_PRINT | C_NAME | C_NORM | C_HEX | C_PATH, /* $63 c */ + C_ALL | C_PRINT | C_NAME | C_NORM | C_HEX | C_PATH, /* $64 d */ + C_ALL | C_PRINT | C_NAME | C_NORM | C_HEX | C_PATH, /* $65 e */ + C_ALL | C_PRINT | C_NAME | C_NORM | C_HEX | C_PATH, /* $66 f */ + C_ALL | C_PRINT | C_NAME | C_NORM | C_PATH, /* $67 g */ + C_ALL | C_PRINT | C_NAME | C_NORM | C_PATH, /* $68 h */ + C_ALL | C_PRINT | C_NAME | C_NORM | C_PATH, /* $69 i */ + C_ALL | C_PRINT | C_NAME | C_NORM | C_PATH, /* $6A j */ + C_ALL | C_PRINT | C_NAME | C_NORM | C_PATH, /* $6B k */ + C_ALL | C_PRINT | C_NAME | C_NORM | C_PATH, /* $6C l */ + C_ALL | C_PRINT | C_NAME | C_NORM | C_PATH, /* $6D m */ + C_ALL | C_PRINT | C_NAME | C_NORM | C_PATH, /* $6E n */ + C_ALL | C_PRINT | C_NAME | C_NORM | C_PATH, /* $6F o */ + + C_ALL | C_PRINT | C_NAME | C_NORM | C_PATH, /* $70 p */ + C_ALL | C_PRINT | C_NAME | C_NORM | C_PATH, /* $71 q */ + C_ALL | C_PRINT | C_NAME | C_NORM | C_PATH, /* $72 r */ + C_ALL | C_PRINT | C_NAME | C_NORM | C_PATH, /* $73 s */ + C_ALL | C_PRINT | C_NAME | C_NORM | C_PATH, /* $74 t */ + C_ALL | C_PRINT | C_NAME | C_NORM | C_PATH, /* $75 u */ + C_ALL | C_PRINT | C_NAME | C_NORM | C_PATH, /* $76 v */ + C_ALL | C_PRINT | C_NAME | C_NORM | C_PATH, /* $77 w */ + C_ALL | C_PRINT | C_NAME | C_NORM | C_PATH, /* $78 x */ + C_ALL | C_PRINT | C_NAME | C_NORM | C_PATH, /* $79 y */ + C_ALL | C_PRINT | C_NAME | C_NORM | C_PATH, /* $7A z */ + C_ALL | C_PRINT | C_NORM | C_PATH, /* $7B { */ + C_ALL | C_PRINT | C_NORM, /* $7C | */ + C_ALL | C_PRINT | C_NORM | C_PATH, /* $7D } */ + C_ALL | C_PRINT | C_NORM, /* $7E ~ */ + C_ALL, /* $7F DEL */ + + 0, /* $80 */ + 0, /* $81 */ + 0, /* $82 */ + 0, /* $83 */ + 0, /* $84 */ + 0, /* $85 */ + 0, /* $86 */ + 0, /* $87 */ + 0, /* $88 */ + 0, /* $89 */ + 0, /* $8A */ + 0, /* $8B */ + 0, /* $8C */ + 0, /* $8D */ + 0, /* $8E */ + 0, /* $8F */ + + 0, /* $90 */ + 0, /* $91 */ + 0, /* $92 */ + 0, /* $93 */ + 0, /* $94 */ + 0, /* $95 */ + 0, /* $96 */ + 0, /* $97 */ + 0, /* $98 */ + 0, /* $99 */ + 0, /* $9A */ + 0, /* $9B */ + 0, /* $9C */ + 0, /* $9D */ + 0, /* $9E */ + 0, /* $9F */ + + 0, /* $A0 */ + 0, /* $A1 */ + 0, /* $A2 */ + 0, /* $A3 */ + 0, /* $A4 */ + 0, /* $A5 */ + 0, /* $A6 */ + 0, /* $A7 */ + 0, /* $A8 */ + C_ALL | C_PRINT | C_NORM | C_PATH, /* $A9 © */ + 0, /* $AA */ + 0, /* $AB */ + 0, /* $AC */ + 0, /* $AD */ + 0, /* $AE */ + 0, /* $AF */ + + 0, /* $B0 */ + 0, /* $B1 */ + 0, /* $B2 */ + 0, /* $B3 */ + 0, /* $B4 */ + 0, /* $B5 */ + 0, /* $B6 */ + 0, /* $B7 */ + 0, /* $B8 */ + 0, /* $B9 */ + 0, /* $BA */ + 0, /* $BB */ + 0, /* $BC */ + 0, /* $BD */ + 0, /* $BE */ + 0, /* $BF */ + + 0, /* $C0 */ + 0, /* $C1 */ + 0, /* $C2 */ + 0, /* $C3 */ + C_ALL | C_PRINT | C_NORM | C_PATH, /* $C4 Ä */ + 0, /* $C5 */ + 0, /* $C6 */ + 0, /* $C7 */ + 0, /* $C8 */ + 0, /* $C9 */ + 0, /* $CA */ + 0, /* $CB */ + 0, /* $CC */ + 0, /* $CD */ + 0, /* $CE */ + 0, /* $CF */ + + 0, /* $D0 */ + 0, /* $D1 */ + 0, /* $D2 */ + 0, /* $D3 */ + 0, /* $D4 */ + 0, /* $D5 */ + C_ALL | C_PRINT | C_NORM | C_PATH, /* $D6 Ö */ + 0, /* $D7 */ + 0, /* $D8 */ + 0, /* $D9 */ + 0, /* $DA */ + 0, /* $DB */ + C_ALL | C_PRINT | C_NORM | C_PATH, /* $DC Ü */ + 0, /* $DD */ + 0, /* $DE */ + C_ALL | C_PRINT | C_NORM | C_PATH, /* $DF ß */ + + 0, /* $E0 */ + 0, /* $E1 */ + 0, /* $E2 */ + 0, /* $E3 */ + C_ALL | C_PRINT | C_NORM | C_PATH, /* $E4 ä */ + 0, /* $E5 */ + 0, /* $E6 */ + 0, /* $E7 */ + 0, /* $E8 */ + 0, /* $E9 */ + 0, /* $EA */ + 0, /* $EB */ + 0, /* $EC */ + 0, /* $ED */ + 0, /* $EE */ + 0, /* $EF */ + + 0, /* $F0 */ + 0, /* $F1 */ + 0, /* $F2 */ + 0, /* $F3 */ + 0, /* $F4 */ + 0, /* $F5 */ + C_ALL | C_PRINT | C_NORM | C_PATH, /* $F6 ö */ + 0, /* $F7 */ + 0, /* $F8 */ + 0, /* $F9 */ + 0, /* $FA */ + 0, /* $FB */ + C_ALL | C_PRINT | C_NORM | C_PATH, /* $FC ü */ + 0, /* $FD */ + 0, /* $FE */ + 0 /* $FF */ + }; diff --git a/cputest/adis/util.c b/cputest/adis/util.c new file mode 100644 index 00000000..75654c80 --- /dev/null +++ b/cputest/adis/util.c @@ -0,0 +1,999 @@ +/* + * Change history + * $Log: util.c,v $ + * + * Revision 3.1 09/10/15 Matt_Hey + * New: col_put(), add_str(), str_len(). Many other changes. + * Addressing modes changed to new style, lower case + * + * Revision 3.0 93/09/24 17:54:29 Martin_Apel + * New feature: Added extra 68040 FPU opcodes + * + * Revision 2.3 93/07/18 22:56:58 Martin_Apel + * *** empty log message *** + * + * Revision 2.2 93/07/10 13:02:35 Martin_Apel + * Major mod.: Added full jump table support. Seems to work quite well + * + * Revision 2.1 93/07/08 22:29:31 Martin_Apel + * + * Minor mod.: Displacements below 4 used with pc indirect indexed are + * not entered into the symbol table anymore + * + * Revision 2.0 93/07/01 11:54:56 Martin_Apel + * *** empty log message *** + * + * Revision 1.17 93/07/01 11:45:00 Martin_Apel + * Minor mod.: Removed $-sign from labels + * Minor mod.: Prepared for tabs instead of spaces + * + * Revision 1.16 93/06/16 20:31:31 Martin_Apel + * Minor mod.: Removed #ifdef FPU_VERSION and #ifdef MACHINE68020 + * + * Revision 1.15 93/06/04 11:56:35 Martin_Apel + * New feature: Added -ln option for generation of ascending label numbers + * + * Revision 1.14 93/06/03 20:30:17 Martin_Apel + * Minor mod.: Additional linefeed generation for end instructions has been + * moved to format_line + * New feature: Added -a switch to generate comments for file offsets + * + * Revision 1.13 93/05/27 20:50:48 Martin_Apel + * Bug fix: Register list was misinterpreted for MOVEM / FMOVEM + * instructions. + * + */ + +#include "defs.h" +#include "string_recog.h" +#include + +/* static char rcsid [] = "$Id: util.c,v 3.1 09/10/15 Martin_Apel Exp $"; */ + +/**********************************************************************/ +/* A few routines doing string handling such as formatting */ +/* a hex value, formatting the register list for MOVEM */ +/* instructions, different address modes... */ +/* sprintf would have been much easier but sloooow !!! */ +/**********************************************************************/ + +const char hex_chars [] = "0123456789abcdef"; /* for format() functions */ + +/**************************************************************************/ + +char *str_cpy (char *dest, const char *src) + +/* str_cpy() returns new dest (end of str), strcpy() returns old dest */ +{ +while (*dest++ = *src++); +return (dest - 1); +} + +/**************************************************************************/ + +char *str_cat (char *dest, const char *src) + +/* str_cat() returns new dest (end of str), strcat() returns old dest */ +{ +while (*dest) + dest++; +while(*dest++ = *src++); +return (dest - 1); +} + +/**************************************************************************/ + +BOOL is_str (char *maybe_string, uint max_len) + +{ +register uchar *tmp_str; +uchar *last_char; + +tmp_str = (uchar*) maybe_string; +last_char = tmp_str + max_len; +while (IS_VALID (*tmp_str) && (tmp_str < last_char)) + tmp_str++; +if ((*tmp_str != 0) || ((char*)tmp_str == maybe_string)) /* single 0 char is not a string */ + return (FALSE); +return (TRUE); +} + +/**************************************************************************/ + +int str_len (char *maybe_string, uint max_len) + +/* str_len() returns string length or 0 if not a valid string */ +{ +register uchar *tmp_str; +uchar *last_char; + +tmp_str = (uchar*) maybe_string; +last_char = tmp_str + max_len; +while (IS_VALID (*tmp_str) && (tmp_str < last_char)) + tmp_str++; + +if (*tmp_str == 0) + return ((char*)tmp_str - maybe_string); +return (0); +} + +/**************************************************************************/ + +void emit (char *string) + +/* fputs a string */ +{ +#ifdef DEBUG +if (out == NULL) + { + fprintf (stderr, "ERROR: Attempt to write to closed file in emit()\n"); + ExitADis (); + } +#endif + +if (fputs (string, out) == EOF) + { + fprintf (stderr, "ERROR: Writing output file\n"); + ExitADis (); + } +} + +/**************************************************************************/ + +void col_emit (char *string) + +/* fputs leading OPCODE_COL blanks followed by string */ +{ + +#ifdef DEBUG +if (out == NULL) + { + fprintf (stderr, "ERROR: Attempt to write to closed file in col_emit()\n"); + ExitADis (); + } +#endif + +if (fputs (spaces, out) == EOF) + { + fprintf (stderr, "ERROR: Writing output file\n"); + ExitADis (); + } +if (fputs (string, out) == EOF) + { + fprintf (stderr, "ERROR: Writing output file\n"); + ExitADis (); + } +} + +/**************************************************************************/ + +char *format_line (char *to, BOOL commented, int instr_words) + +/* format opcode, src and dest to to */ +{ +char *tmp_str; +register int i; +register char reg_space_char = space_char; + +tmp_str = to; +i = OPCODE_COL; +do + { + *to++ = reg_space_char; + i--; + } +while (i > 0); +to = str_cpy (to, opcode); + +if (!(src [0] == 0 && dest [0] == 0)) + { + i = PARAM_COL - (to - tmp_str); + do + { + *to++ = reg_space_char; + i--; + } + while (i > 0); + if (dest [0] == 0) + to = str_cpy (to, src); + else if (src [0] == 0) + to = str_cpy (to, dest); + else + { + to = str_cpy (to, src); + *to++ = ','; + to = str_cpy (to, dest); + } + } + +if (commented && comment) + { + ULONG offset; + + i = COMMENT_COL - (to - tmp_str); + do + { + *to++ = reg_space_char; + i--; + } + while (i > 0); + *to++ = ';'; + + if ((comment & 0x8) == 8) /* btst #3 */ + { + ULONG flags_l; + + *to++ = ' '; + flags_l = *(flags + (current_ref - first_ref)); + if (flags_l & FLAG_BYTE) + *to++ = 'b'; + else + *to++ = '-'; + if (flags_l & FLAG_WORD) + *to++ = 'w'; + else + *to++ = '-'; + if (flags_l & FLAG_LONG) + *to++ = 'l'; + else + *to++ = '-'; + if (flags_l & FLAG_SIGNED) + *to++ = 's'; + else + *to++ = '-'; + if (flags_l & FLAG_RELOC) + *to++ = 'R'; + else + *to++ = '-'; + if (flags_l & FLAG_STRING) + *to++ = 'S'; + else + *to++ = '-'; + if (flags_l & FLAG_TABLE) + *to++ = 'T'; + else + *to++ = '-'; + if (flags_l & FLAG_CODE) + *to++ = 'C'; + else + *to++ = '-'; + } + if (!(comment & 0x06)) /* comment=0 or comment=1 */ + { + /* relocation offset */ + offset = current_ref; + } + else if ((comment & 0x2) == 2) /* btst #1 */ + { + /* hunk offset */ + offset = current_ref - first_ref; + } + else + { + /* file offset */ + offset = current_ref - first_ref + *(hunk_offset + current_hunk); + } + *to++ = ' '; + to = format_ulx_no_dollar (to, offset); + if (EVEN (comment)) + { + if (instr_words) + { + *to++ = ' '; + *to++ = ':'; + for (i = 0; i < instr_words; i++) + { + *to++ = ' '; + to = format_ulx_digits (to, *(code + i), 4L); + } + } + } + } +#if 0 +*to++ = 0x0a; /* lf=0x0a */ +if (instr_end) /* extra LF after routines looks nicer */ + *to++ = 0x0a; /* lf=0x0a */ +#endif +*to = 0; +return (to); +} + +/**************************************************************************/ + +char *format_ulx (char *to, ULONG val) + +/* Converts a ULONG (or UWORD) to a hex string. Returns ptr to EOS. */ +{ + +if (val <= 9) + { + *to++ = (char)(val + '0'); + *to = 0; + return (to); + } +else + { + char stack [8], + *sp; + + sp = stack; + do + { + *sp++ = val & 0xf; /* MOD 16 */ + val = val >> 4; /* DIV 16 */ + } + while (val != 0); + *to++ = '$'; + do + *to++ = hex_chars [*(--sp)]; + while (sp != stack); + *to = 0; + return (to); + } +} + +/**************************************************************************/ + +char *format_lx (char *to, ULONG val) + +/* Converts a long to a hex string. Returns ptr to EOS. */ +{ + +if ((LONG)val < 0) + { + val = 0-val; + *to++ = '-'; + } + +if (val <= 9) + { + *to++ = (char)(val + '0'); + *to = 0; + return (to); + } +else + { + char stack [8], + *sp; + + sp = stack; + do + { + *sp++ = val & 0xf; /* MOD 16 */ + val = val >> 4; /* DIV 16 */ + } + while (val != 0); + *to++ = '$'; + do + *to++ = hex_chars [*(--sp)]; + while (sp != stack); + *to = 0; + return (to); + } +} + +/**************************************************************************/ + +char *format_ulx_no_dollar (char *to, ULONG val) + +/* Converts a ULONG (or UWORD) to a hex string. Returns ptr to EOS. + The same as format_ulx but without the dollar sign. */ +{ +char stack [8], + *sp; + +sp = stack; +do + { + *sp++ = val & 0xf; /* MOD 16 */ + val = val >> 4; /* DIV 16 */ + } +while (val != 0); +do + *to++ = hex_chars [*(--sp)]; +while (sp != stack); + +*to = 0; +return (to); +} + +/**************************************************************************/ + +/* Currently unused +char *format_lx_no_dollar (char *to, ULONG val) + +// Converts a long to a hex string. Returns ptr to EOS. +// The same as format_lx but without the dollar sign +{ +char stack [8], + *sp; + +if ((LONG)val < 0) + { + val = -val; + *to++ = '-'; + } + +sp = stack; +do + { + *sp++ = val & 0xf; // MOD 16 + val = val >> 4; // DIV 16 + } +while (val != 0); +do + *to++ = hex_chars [*(--sp)]; +while (sp != stack); + +*to = 0; +return (to); +} +*/ + +/**************************************************************************/ + +char *format_ulx_digits (char *to, ULONG val, uint digits) + +/* Convert val to a hex string of (up to 8) digits. Returns ptr to EOS. + No dollar sign. Leading zeros included. + digits = 4 for a UWORD + digits = 8 for a ULONG +*/ +{ +char stack [32], + *sp; + +sp = stack; +do + { + *sp++ = val & 0xf; /* MOD 16 */ + val = val >> 4; /* DIV 16 */ + digits--; + } +while (digits != 0); +do + *to++ = hex_chars [*(--sp)]; +while (sp != stack); + +*to = 0; +return (to); +} + +/**************************************************************************/ + +void format_reg_list (char *to, ushort list, BOOL incr_list, ushort reglist_offset) + +{ +register int i; +register long mylist; /* list in order a7-a0/d7-d0 */ +short last_set; +BOOL regs_used; + + +if (!incr_list) + { + mylist = 0; + for (i = 0; i < 16; i++) + { + if (list & (1 << i)) + mylist |= 1 << (15 - i); + } + } +else + mylist = list; + +last_set = -1; +regs_used = FALSE; +for (i = 0; i < 17; i++) + { + if ((mylist & (1 << i)) && last_set == -1) + { + if (regs_used) + *to++ = '/'; + to = str_cpy (to, reg_names [i + reglist_offset]); + last_set = i; + regs_used = TRUE; + } + else if (!(mylist & (1 << i))) + { + if (last_set == i - 1) + last_set = -1; + else if (last_set != -1) + { + *to++ = '-'; + to = str_cpy (to, reg_names [i - 1 + reglist_offset]); + last_set = -1; + } + } + if (i == 7 && (mylist & 0x180) == 0x180) + { + if (last_set != 7) + /* d7 and a0 both used and still in a list */ + { + *to++ = '-'; + to = str_cpy (to, reg_names [7 + reglist_offset]); + } + last_set = -1; + } + } +} + +/**************************************************************************/ + +char *immed (char *to, ULONG val) + +{ +/* e.g. #$17 */ + +*to++ = '#'; +return (format_ulx (to, val)); +} + +/**************************************************************************/ + +void indirect (char *to, ushort reg_num) + +{ +/* e.g. (a0) */ + +*to++ = '('; +to = str_cpy (to, reg_names [reg_num]); +*to++ = ')'; +*to = 0; +} + +/**************************************************************************/ + +void pre_dec (char *to, ushort reg_num) + +{ +/* e.g. -(a0) */ + +*to++ = '-'; +*to++ = '('; +to = str_cpy (to, reg_names [reg_num]); +*to++ = ')'; +*to = 0; +} + +/**************************************************************************/ + +void post_inc (char *to, ushort reg_num) + +{ +/* e.g. (a0)+ */ + +*to++ = '('; +to = str_cpy (to, reg_names [reg_num]); +*to++ = ')'; +*to++ = '+'; +*to = 0; +} + +/**************************************************************************/ + +void disp_an (char *to, ushort reg_num, WORD disp) + +{ +/* e.g. 4(a0) or (4,a0) */ + +if (old_style) + { + to = format_x (to, disp); + *to++ = '('; + } +else + { + *to++ = '('; + to = format_x (to, disp); + *to++ = ','; + } +to = str_cpy (to, reg_names [reg_num]); +*to++ = ')'; +*to = 0; +} + +/**************************************************************************/ + +void disp_an_indexed (char *to, ushort an, BYTE disp, ushort index_reg, + ushort scale, ushort size) + +{ +/* e.g. 4(a0,d0.w*4) or (4,a0,d0.w*4) */ +/* address register indirect with index (8 bit displacement) */ +/* the displacement, address register, and index register are mandantory */ + +if (!old_style) + *to++ = '('; + +if (!(disp == 0 && optimize)) + to = format_x (to, (WORD)disp); + +if (old_style) + *to++ = '('; +else if (!(disp == 0 && optimize)) + *to++ = ','; + +to = str_cpy (to, reg_names [an]); +*to++ = ','; +to = str_cpy (to, reg_names [index_reg]); +*to++ = '.'; +if (size == 4) + *to++ = 'l'; +else + *to++ = 'w'; +if (scale != 1) + { + *to++ = '*'; + *to++ = scale + '0'; + } +*to++ = ')'; +*to = 0; +} + +/**************************************************************************/ + +void disp_pc_indexed (char *to, ULONG ref, BYTE disp, ushort index_reg, + ushort scale, ushort size) + +{ +/* e.g. 4(pc,d0.w*4) or (4,pc,d0.w*4) */ +/* pc indirect with index (8 bit displacement) */ +/* the displacement, pc, and index register are mandantory */ + +if (!old_style) + *to++ = '('; + +if (!((*code & 0xffc0) == 0x4ec0)) /* not jmp */ + to = gen_label_ref (to, ref); +else if (!(disp == 0 && optimize)) + to = format_x (to, (WORD)disp); + +if (old_style) + *to++ = '('; +else if (!(disp == 0 && optimize)) + *to++ = ','; + +to = str_cpy (to, reg_names [PC]); +*to++ = ','; +to = str_cpy (to, reg_names [index_reg]); +*to++ = '.'; +if (size == 4) + *to++ = 'l'; +else + *to++ = 'w'; +if (scale != 1) + { + *to++ = '*'; + *to++ = scale + '0'; + } +*to++ = ')'; +*to = 0; +} + +/**************************************************************************/ + +uint full_extension (char *to, UWORD *instr_ext, ushort mode, ushort reg) + +{ +/* address register indirect with index (base displacement) */ +/* the displacement, address register and index register are all optional */ + +/* 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 */ +/* D/A Register W/L Scale 1 BS IS BD size 0 I/IS */ + +/* D/A is Index register type %0=Dn, %1=An */ +/* W/L is Word/Longword index size %0=sign extended word, %1=longword */ +/* Scale is Scale factor %00=1, %01=2, %10=4, %11=8 */ +/* BS is Base Register Suppress %0=add base register, %1=suppress */ +/* IS is Index Suppress %0=evaluate & add index operand, %1=suppress */ +/* BD size is Base Displacement size %00=reserved, %01=null, %10=word, %11=long */ +/* I/IS is Index/Indirect Select +/* +select = (no_index_reg >> 3) | (*(instr_ext) & 0x0007); +switch (select) + { + case 0x0: // %0000 No memory indirect action + case 0x1: // %0001 Indirect Preindexed with null od + case 0x2: // %0010 Indirect Preindexed with word od + case 0x3: // %0011 Indirect Preindexed with long od + case 0x4: // %0100 Reserved + case 0x5: // %0101 Indirect Postindexed with null od + case 0x6: // %0110 Indirect Postindexed with word od + case 0x7: // %0111 Indirect Postindexed with long od + + // index register suppressed + case 0x8: // %1000 No memory indirect action + case 0x9: // %1001 Memory indirect with null od + case 0xa: // %1010 Memory indirect with word od + case 0xb: // %1011 Memory indirect with long od + case 0xc: // %1100 Reserved + case 0xd: // %1101 Reserved + case 0xe: // %1110 Reserved + case 0xf: // %1111 Reserved + } +*/ + +int bd_size, + od_size; +UWORD full_ext_w, + scale, + post_indexed, + no_index_reg, + no_base_reg; +WORD *next_instr_ext; + +full_ext_w = *instr_ext; +next_instr_ext = (WORD*)instr_ext + 1; + +no_index_reg = (full_ext_w & 0x0040); /* %1000000, bit #6 */ + +/* check for validity of instr word */ +if ((full_ext_w & 0x0008) || !(full_ext_w & 0x0030) || + (full_ext_w & 0x0007) == 4 || ((full_ext_w & 0x0007) > 4 && no_index_reg)) + { + instr_bad = TRUE; + return (0); + } + +no_base_reg = (full_ext_w & 0x0080); /* %10000000, bit #7 */ +post_indexed = (full_ext_w & 0x0004); /* %100, bit #2 */ +bd_size = ((full_ext_w >> 4) & 0x0003) - 1; /* -1=invalid 0=NULL, 1=word, 2=longword */ +od_size = (full_ext_w & 0x0003) - 1; /* -1=invalid, 0=NULL, 1=word, 2=longword */ + +if (!(no_index_reg && no_base_reg && od_size < 0)) + { + *to++ = '('; + if (od_size >= 0) + *to++ = '['; + } + +if (bd_size == 1) /* .w? */ + { + if (mode == 7 && !no_base_reg) /* pc relative && pc not suppressed? */ + { + ULONG b_offset = current_ref + ((instr_ext - code) << 1); + if (pass2) + enter_ref (b_offset + *(next_instr_ext++), NULL, ACC_UNKNOWN); + else + to = gen_label_ref (to, b_offset + *(next_instr_ext++)); + } + else + { + to = format_x (to, *(next_instr_ext++)); + if (!optimize) + { + *to++ = '.'; + *to++ = 'w'; + } + } + } +else if (bd_size == 2) /* .l? */ + { + ULONG b_offset = current_ref + (((UWORD*)instr_ext - code) << 1); + if (FLAGS_RELOC (b_offset + 2)) /* relocated absolute (to a label) */ + { + if (pass2) + enter_ref (*((LONG*)(next_instr_ext)), NULL, ACC_UNKNOWN); + else + to = gen_label_ref (to, *((LONG*)(next_instr_ext))); + } + else if (mode == 7 && !no_base_reg) /* pc relative && pc not suppressed? */ + { + if (pass2) + enter_ref (b_offset + *((LONG*)(next_instr_ext)), NULL, ACC_UNKNOWN); + else + to = gen_label_ref (to, b_offset + *((LONG*)(next_instr_ext))); + } + else + { + to = format_lx (to, *((LONG*)(next_instr_ext))); + if (!optimize) + { + *to++ = '.'; + *to++ = 'l'; + } + } + next_instr_ext += 2; + } +else if (bd_size == 0 && no_base_reg && no_index_reg) /* absolute with NULL bd */ + *to++ = '0'; + +if (!no_base_reg) /* base register? */ + { + if (bd_size > 0) + *to++ = ','; + if (mode == 7) /* pc relative? */ + reg = 8; + to = str_cpy (to, reg_names [reg + 8]); + } + +if (!no_index_reg) + { + if (post_indexed) + *to++ = ']'; + if (bd_size != 0 || !no_base_reg) + *to++ = ','; + to = str_cpy (to, reg_names [full_ext_w >> 12]); + *to++ = '.'; + if (full_ext_w & 0x0800) + *to++ = 'l'; + else + *to++ = 'w'; + scale = 1 << ((full_ext_w & 0x0600) >> 9); + if (scale != 1) + { + *to++ = '*'; + *to++ = scale + '0'; + } + } + +if (!post_indexed && od_size >= 0) + *to++ = ']'; + +if (od_size == 1) /* .w? */ + { + *to++ = ','; + to = format_x (to, *(next_instr_ext++)); + if (!optimize) + { + *to++ = '.'; + *to++ = 'w'; + } + } +else if (od_size == 2) /* .l? */ + { + *to++ = ','; + to = format_lx (to, *((LONG*)(next_instr_ext))); + if (!optimize) + { + *to++ = '.'; + *to++ = 'l'; + } + next_instr_ext += 2; + } + +if (!(no_index_reg && no_base_reg && od_size < 0)) + *to++ = ')'; +*to = 0; + +return ((uint)((UWORD*)next_instr_ext - instr_ext)); +} + +/**************************************************************************/ + +char *gen_xref (char *to, ULONG address) + +{ +to = str_cpy (to, "XREF "); +to = gen_label_ref (to, address); +*to++ = 0x0a; /* lf=$0a */ +*to = 0; +return (to); +} + +/**************************************************************************/ + +char *gen_label_ref (char *to, ULONG ref) + +/* generates a label reference and returns new dest (end of str) */ +{ +char *label; +UWORD access; + +if (find_ref (ref, &label, &access) && label != 0) + { + to = str_cpy (to, label); + return (to); + } +to = str_cpy (to, "lab_"); +to = format_ux_no_dollar (to, ref); +return (to); +} + +/**************************************************************************/ + +char *gen_label (char *to, ULONG ref) + +/* generates a label if needed and returns new dest (end of str) */ +{ +char *label; +UWORD access; + +if (find_ref (ref, &label, &access)) + { + if (label == NULL) + { + to = str_cpy (to, "lab_"); + to = format_ux_no_dollar (to, ref); + } + else + to = str_cpy (to, label); + *to++ = ':'; + *to++ = 0x0a; /* lf=$0a */ + } +*to = 0; +return (to); +} + +/**************************************************************************/ + +void assign_label_names (void) + +/**********************************************************************/ +/* Assigns each label an ascending number instead of its address */ +/**********************************************************************/ +{ +uint label_count = 1; +ULONG ref = 0; +UWORD access; +char *old_name; +char label_name [16]; + +while ((ref = next_ref (ref, total_size, &access)) != total_size) + { + find_ref (ref, &old_name, &access); + if (old_name == NULL) + { + format_ux_no_dollar (str_cpy (label_name, "lab_"), label_count++); + enter_ref (ref, label_name, access); + } + } +} + + +void ExitADis(void) +{ +} +void enter_ref(ULONG ref, char *name, UWORD access_type) +{ +} +BOOL find_ref(ULONG ref, char **name, UWORD *access_type) +{ + return FALSE; +} +void enter_jmptab(ULONG start, ULONG offset) +{ +} +ULONG next_ref(ULONG from, ULONG to, UWORD *access_type) +{ + return 0; +} + +uint disasm_instr(UWORD *instr, char *out) + +/**********************************************************************/ +/* Returns number of 16 bit words disassembled */ +/**********************************************************************/ + +{ + struct opcode_entry *op; + uint size = 0; + + set_pass3; + + opcode[0] = src[0] = dest[0] = 0; + instr_bad = FALSE; /* global variable TRUE when unknown or corrupt instr is found */ + instr_end = FALSE; /* global variable TRUE at rts, bra, jmp, etc. */ + code = instr; /* global variable */ + + for (op = &(opcode_table[(instr[0]) >> 6]); + size == 0; + op = &(opcode_table[op->chain])) + { + /* Test for validity of ea_mode */ + if (op->modes & (1 << MODE_NUM(*instr))) + { + if ((MODE_NUM(*instr) == 7) && !(op->submodes & (1 << REG_NUM(*instr)))) + continue; + + if (pass3 && op->mnemonic != 0) + { + str_cpy(opcode, op->mnemonic); + } + size = (*op->handler) (op); + } + } + format_line(out, FALSE, 0); + return (size); +} diff --git a/cputest/asm.S b/cputest/asm.S index fbe8bf15..70a59add 100644 --- a/cputest/asm.S +++ b/cputest/asm.S @@ -315,6 +315,7 @@ _exceptionfpu: movem.l d0-d7/a0-a6,(a0) move.l (sp)+,8*4(a0) + move.l sp,S_EXCFRAME(a0) move.w (sp)+,S_SR+2(a0) move.l (sp)+,S_PC(a0) move.w (sp),d0 diff --git a/cputest/cputestgen.ini b/cputest/cputestgen.ini index 8274d408..8c9b758f 100644 --- a/cputest/cputestgen.ini +++ b/cputest/cputestgen.ini @@ -9,7 +9,7 @@ cpu=68020 cpu_address_space=32 ; FPU model (empty string or 0, 68881, 68882, 68040, 68060) -; Enable only when testing FPU. Enabled FPU mode will slow down execution. +; Enable only when testing FPU. Enabled FPU mode will slow down native test execution even when not testing FPU instructions. fpu= ; Write generated instructions to standard output. Always disabled in "all" mode. @@ -18,18 +18,18 @@ verbose=1 ; Where to generate test files path=data/ -; Low address space limits (0x0000 to 0x8000 is complete space) +; Low address space limits. Real hardware must have RAM in this space. Comment out to disable. test_low_memory_start=0x0000 test_low_memory_end=0x8000 -; High address space limits (0x00ff8000 to 0x01000000 is complete space) +; High address space limits (0x00ff8000 to 0x01000000 is complete space). Comment out to disable. ;test_high_memory_start=0x00ff8000 ;test_high_memory_end=0x01000000 -; ROM high address space +; ROM high address space. High memory is only used for read tests. high_rom=D:\amiga\roms\Kickstart v3.1 rev 40.63 (1993)(Commodore)(A500-A600-A2000)[!].rom -; main test memory start and size (real hardware must have RAM in same address space) +; main test memory start and size (real hardware must have RAM in this address space) test_memory_start=0x780000 test_memory_size=0x080000 @@ -37,11 +37,11 @@ test_memory_size=0x080000 ; 0 = do not generate address errors ; 1 = include address errors ; 2 = only generate test instructions that generate address errors -feature_exception3_data=1 +feature_exception3_data=0 ; test branches to odd addresses -; same as above -feature_exception3_instruction=1 +; same options as above +feature_exception3_instruction=0 ; SR extra mask. ; 0x8000 = T1 @@ -55,7 +55,7 @@ feature_sr_mask=0x0000 ; generate loop test: label: dbf dn,label ; value: 0 = disabled, >0 = number of loops -feature_loop_mode=10 +feature_loop_mode=0 feature_loop_mode_register=7 ; 68020+ addressing modes (this makes test files much larger if other addressing modes are also enabled) @@ -69,7 +69,7 @@ feature_full_extension_format=0 feature_addressing_modes_src= feature_addressing_modes_dst= -; mnemonics separated by comma or all. -; all = generate all. tst = generate tst.b, tst.w and tst.l. tst.l = generate only tst.l -mode=not.b - +; mnemonics separated by comma or all/fall. +; all = generate all CPU tests. tst = generate tst.b, tst.w and tst.l. tst.l = generate only tst.l +; fall = generate all FPU tests. +mode=chk2.b diff --git a/cputest/main.c b/cputest/main.c index 359f7789..f338f7f5 100644 --- a/cputest/main.c +++ b/cputest/main.c @@ -54,6 +54,8 @@ static uae_u8 *opcode_memory; static uae_u32 opcode_memory_addr; static uae_u8 *low_memory; static uae_u8 *high_memory; +static uae_u32 low_memory_size; +static uae_u32 high_memory_size; static uae_u8 *test_memory; static uae_u32 test_memory_addr; static uae_u32 test_memory_size; @@ -75,15 +77,15 @@ static uae_u32 cpustatearraynew[] = { 0x00000000, // MSP }; -static uae_u8 low_memory_temp[32768]; -static uae_u8 high_memory_temp[32768]; -static uae_u8 low_memory_back[32768]; -static uae_u8 high_memory_back[32768]; +static uae_u8 *low_memory_temp; +static uae_u8 *high_memory_temp; +static uae_u8 *low_memory_back; +static uae_u8 *high_memory_back; static uae_u32 vbr[256]; static char inst_name[16+1]; -#ifdef _MSC_VER +#ifndef M68K static char outbuffer[40000]; #else static char outbuffer[4000]; @@ -97,7 +99,7 @@ static int quit; static uae_u8 ccr_mask; static uae_u32 addressing_mask = 0x00ffffff; -#ifdef _MSC_VER +#ifndef M68K #define xmemcpy memcpy @@ -203,15 +205,15 @@ static void start_test(void) if (test_active) return; -#ifndef _MSC_VER +#ifdef M68K if (lmem_rom > 0) { - if (memcmp(low_memory, low_memory_temp, 32768)) { + if (memcmp(low_memory, low_memory_temp, low_memory_size)) { printf("Low memory ROM mismatch!\n"); exit(0); } } if (hmem_rom > 0) { - if (memcmp(high_memory, high_memory_temp, 32768)) { + if (memcmp(high_memory, high_memory_temp, high_memory_size)) { printf("High memory ROM mismatch!\n"); exit(0); } @@ -222,13 +224,13 @@ static void start_test(void) enable_data = tosuper(0); - memcpy(low_memory_back, low_memory, 32768); + memcpy(low_memory_back, low_memory, low_memory_size); if (!hmem_rom) - memcpy(high_memory_back, high_memory, 32768); + memcpy(high_memory_back, high_memory, high_memory_size); - memcpy(low_memory, low_memory_temp, 32768); + memcpy(low_memory, low_memory_temp, low_memory_size); if (!hmem_rom) - memcpy(high_memory, high_memory_temp, 32768); + memcpy(high_memory, high_memory_temp, high_memory_size); if (cpu_lvl == 0) { uae_u32 *p = (uae_u32 *)vbr_zero; @@ -253,9 +255,9 @@ static void end_test(void) return; test_active = 0; - memcpy(low_memory, low_memory_back, 32768); + memcpy(low_memory, low_memory_back, low_memory_size); if (!hmem_rom) - memcpy(high_memory, high_memory_back, 32768); + memcpy(high_memory, high_memory_back, high_memory_size); if (cpu_lvl > 0) { setvbr(oldvbr); @@ -303,11 +305,22 @@ static void pl(uae_u8 *p, uae_u32 v) p[2] = v >> 8; p[3] = v >> 0; } +static void pw(uae_u8 *p, uae_u32 v) +{ + p[0] = v >> 8; + p[1] = v >> 0; +} + static uae_u32 gl(uae_u8 *p) { return (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | (p[3] << 0); } +static uae_u16 gw(uae_u8 *p) +{ + return (p[0] << 8) | (p[1] << 0); +} + static uae_u8 *restore_fpvalue(uae_u8 *p, struct fpureg *fp) { uae_u8 v = *p++; @@ -317,12 +330,13 @@ static uae_u8 *restore_fpvalue(uae_u8 *p, struct fpureg *fp) endinfo(); exit(0); } - fp->exp = (p[0] << 8) | p[1]; + fp->exp = gw(p); p += 2; fp->m[0] = gl(p); p += 4; fp->m[1] = gl(p); p += 4; + fp->dummy = 0; return p; } @@ -398,7 +412,7 @@ static uae_u8 *restore_rel(uae_u8 *p, uae_u32 *vp, int nocheck) val |= *p++; v = val; if (!nocheck) { - if ((val & addressing_mask) < 0x8000) { + if ((val & addressing_mask) < low_memory_size) { ; // low memory } else if ((val & ~addressing_mask) == ~addressing_mask && val >= 0xfff80000) { ; // high memory @@ -462,20 +476,30 @@ static uae_u8 *get_memory_addr(uae_u8 *p, uae_u8 **addrp) val |= (*p++) << 16; val |= (*p++) << 8; val |= *p++; - if (val < test_memory_addr || val >= test_memory_addr + test_memory_size) { + if (val < low_memory_size) { +#ifndef M68K + uae_u8 *addr = low_memory + val; +#else + uae_u8 *addr = (uae_u8 *)val; +#endif + validate_mode(p[0], CT_MEMWRITE); + *addrp = addr; + return p; + } else if (val >= test_memory_addr && val < test_memory_addr + test_memory_size) { +#ifndef M68K + uae_u8 *addr = test_memory + (val - test_memory_addr); +#else + uae_u8 *addr = (uae_u8 *)val; +#endif + validate_mode(p[0], CT_MEMWRITE); + *addrp = addr; + return p; + } else { end_test(); printf("get_memory_addr CT_ABSOLUTE_LONG outside of test memory! %08x\n", val); endinfo(); exit(0); } -#ifdef _MSC_VER - uae_u8 *addr = test_memory + (val - test_memory_addr); -#else - uae_u8 *addr = (uae_u8 *)val; -#endif - validate_mode(p[0], CT_MEMWRITE); - *addrp = addr; - return p; } case CT_RELATIVE_START_WORD: { @@ -660,7 +684,7 @@ static uae_u8 *restore_data(uae_u8 *p) int Disass68k(long addr, char *labelBuffer, char *opcodeBuffer, char *operandBuffer, char *commentBuffer); void Disasm_SetCPUType(int CPU, int FPU); -static uae_u16 test_sr; +static uae_u16 test_sr, test_ccrignoremask; static uae_u32 test_fpsr, test_fpcr; static void addinfo(void) @@ -683,11 +707,27 @@ static void addinfo(void) strcat(outbp, " "); outbp += strlen(outbp); + uae_u16 disasm_instr(uae_u16 *, char *); +#ifndef M68K + uae_u16 swapped[16]; + for (int i = 0; i < 16; i++) { + swapped[i] = (opcode_memory[i * 2 + 0] << 8) | (opcode_memory[i * 2 + 1] << 0); + } + disasm_instr((uae_u16*)swapped, outbp); +#else + disasm_instr((uae_u16 *)opcode_memory, outbp); +#endif + outbp += strlen(outbp); + *outbp++ = '\n'; + *outbp = 0; + +#if 0 Disasm_SetCPUType(0, 0); char buf1[80], buf2[80], buf3[80], buf4[80]; Disass68k((long)opcode_memory, buf1, buf2, buf3, buf4); sprintf(outbp, "%s %s\n", buf2, buf3); outbp += strlen(outbp); +#endif } struct srbit @@ -755,7 +795,7 @@ static void out_regs(struct registers *r, int before) void *f2 = &test_regs.fpuregs[i]; sprintf(outbp, "FP%d:%c%04x-%08lx%08lx %f", i, - memcmp(f1, f2, 12) ? '*' : ' ', + memcmp(f1, f2, sizeof(struct fpureg)) ? '*' : ' ', f->exp, f->m[0], f->m[1], *((long double*)f)); outbp += strlen(outbp); @@ -791,6 +831,7 @@ static uae_u8 *validate_exception(struct registers *regs, uae_u8 *p, int excnum) uae_u8 *sp = (uae_u8*)regs->excframe; uae_u32 v; uae_u8 excdatalen = *p++; + int size; if (!excdatalen) return p; @@ -842,7 +883,7 @@ static uae_u8 *validate_exception(struct registers *regs, uae_u8 *p, int excnum) pl(exc + 8, v); exclen = 12; break; - case 8: + case 4: v = opcode_memory_addr; p = restore_rel_ordered(p, &v); pl(exc + 8, v); @@ -851,6 +892,12 @@ static uae_u8 *validate_exception(struct registers *regs, uae_u8 *p, int excnum) pl(exc + 12, v); exclen = 16; break; + case 0x0a: + v = 0; + p = restore_value(p, &v, &size); + pw(exc + 0x0a, v); + exclen = 0x0c; + break; default: end_test(); printf("Unknown frame %04x\n", frame); @@ -896,7 +943,7 @@ static uae_u8 *validate_test(uae_u8 *p, int ignore_errors, int ignore_sr) regs_changed[i] = 1; } } - if (last_registers.sr != test_regs.sr) { + if ((last_registers.sr & test_ccrignoremask) != (test_regs.sr & test_ccrignoremask)) { sr_changed = 1; } if (last_registers.pc != test_regs.pc) { @@ -904,7 +951,7 @@ static uae_u8 *validate_test(uae_u8 *p, int ignore_errors, int ignore_sr) } if (fpu_model) { for (int i = 0; i < 8; i++) { - if (memcmp(&last_registers.fpuregs[i], &test_regs.fpuregs[i], 12)) { + if (memcmp(&last_registers.fpuregs[i], &test_regs.fpuregs[i], sizeof(struct fpureg))) { regs_fpuchanged[i] = 1; } } @@ -969,7 +1016,8 @@ static uae_u8 *validate_test(uae_u8 *p, int ignore_errors, int ignore_sr) break; } int mode = v & CT_DATA_MASK; - if (mode < CT_AREG + 8) { + + if (mode < CT_AREG + 8 && (v & CT_SIZE_MASK) != CT_SIZE_FPU) { uae_u32 val = last_registers.regs[mode]; int size; p = restore_value(p, &val, &size); @@ -983,14 +1031,31 @@ static uae_u8 *validate_test(uae_u8 *p, int ignore_errors, int ignore_sr) } regs_changed[mode] = 0; last_registers.regs[mode] = val; + } else if (mode < CT_AREG && (v & CT_SIZE_MASK) == CT_SIZE_FPU) { + struct fpureg val; + p = restore_fpvalue(p, &val); + if (memcmp(&val, &test_regs.fpuregs[mode], sizeof(struct fpureg)) && !ignore_errors) { + addinfo(); + if (dooutput) { + sprintf(outbp, "FP%d: expected %04x-%08lx%08lx but got %04x-%08lx%08lx\n", mode, + val.exp, val.m[0], val.m[1], + test_regs.fpuregs[mode].exp, test_regs.fpuregs[mode].m[0], test_regs.fpuregs[mode].m[1]); + outbp += strlen(outbp); + } + errors++; + } + regs_fpuchanged[mode] = 0; + memcpy(&last_registers.fpuregs[mode], &val, sizeof(struct fpureg)); } else if (mode == CT_SR) { uae_u32 val = last_registers.sr; int size; + // High 16 bit: ignore mask, low 16 bit: SR/CCR p = restore_value(p, &val, &size); - if ((val & sr_undefined_mask) != (test_regs.sr & sr_undefined_mask) && !ignore_errors && !ignore_sr) { + test_ccrignoremask = ~(val >> 16); + if ((val & (sr_undefined_mask | test_ccrignoremask)) != (test_regs.sr & (sr_undefined_mask | test_ccrignoremask)) && !ignore_errors && !ignore_sr) { addinfo(); if (dooutput) { - sprintf(outbp, "SR: expected %04x -> %04x but got %04x\n", test_sr, val, test_regs.sr); + sprintf(outbp, "SR: expected %04x -> %04x but got %04x\n", test_sr, val & 0xffff, test_regs.sr & 0xffff); outbp += strlen(outbp); } errors++; @@ -1114,7 +1179,7 @@ static uae_u8 *validate_test(uae_u8 *p, int ignore_errors, int ignore_sr) if (sr_changed) { addinfo(); if (dooutput) { - sprintf(outbp, "SR: modified %04x -> %04x but expected no modifications\n", last_registers.sr, test_regs.sr); + sprintf(outbp, "SR: modified %04x -> %04x but expected no modifications\n", last_registers.sr & 0xffff, test_regs.sr & 0xffff); outbp += strlen(outbp); } errors++; @@ -1124,8 +1189,9 @@ static uae_u8 *validate_test(uae_u8 *p, int ignore_errors, int ignore_sr) if (regs_fpuchanged[i]) { addinfo(); if (dooutput) { - sprintf(outbp, "FP%d: modified %f -> %f but expected no modifications\n", i, - *((long double *)(&last_registers.fpuregs[i])), *((long double *)(&test_regs.fpuregs[i]))); + sprintf(outbp, "FP%d: modified %04x-%08lx%08lx -> %04x-%08lx%08lx but expected no modifications\n", i, + last_registers.fpuregs[i].exp, last_registers.fpuregs[i].m[0], last_registers.fpuregs[i].m[1], + test_regs.fpuregs[i].exp, test_regs.fpuregs[i].m[0], test_regs.fpuregs[i].m[1]); outbp += strlen(outbp); } errors++; @@ -1197,11 +1263,12 @@ static void process_test(uae_u8 *p) start_test(); + test_ccrignoremask = 0xffff; ahcnt = 0; for (;;) { -#ifdef _MSC_VER +#ifndef M68K outbp = outbuffer; #endif @@ -1492,25 +1559,23 @@ static char path[256]; int main(int argc, char *argv[]) { - int size; char opcode[16]; int stop_on_error = 1; atexit(freestuff); -#ifdef _MSC_VER +#ifndef M68K - char *params[] = { "", "or.w", "", NULL }; + char *params[] = { "", "unpk", "", NULL }; argv = params; argc = 3; strcpy(path, "C:\\projects\\winuae\\src\\cputest\\data\\"); - low_memory = calloc(1, 32768); - high_memory = calloc(1, 32768); vbr_zero = calloc(1, 1024); - cpu_lvl = 0; + cpu_lvl = 2; + #else #define _stricmp stricmp @@ -1524,6 +1589,7 @@ int main(int argc, char *argv[]) high_memory = (uae_u8 *)0xffff8000; cpu_lvl = get_cpu_model(); + #endif if (argc < 2) { @@ -1558,10 +1624,27 @@ int main(int argc, char *argv[]) } } - size = 32768; - load_file(path, "lmem.dat", low_memory_temp, &size); - size = 32768; - load_file(path, "hmem.dat", high_memory_temp, &size); + low_memory_size = -1; + low_memory_temp = load_file(path, "lmem.dat", NULL, &low_memory_size); + high_memory_size = -1; + high_memory_temp = load_file(path, "hmem.dat", NULL, &high_memory_size); + + if (low_memory_size < 0 || !low_memory_temp) { + printf("Couldn't allocate low memory\n"); + return 0; + } + if (high_memory_size < 0 || !high_memory_temp) { + printf("Couldn't allocate low memory\n"); + return 0; + } + +#ifndef M68K + low_memory = calloc(1, low_memory_size); + high_memory = calloc(1, high_memory_size); +#endif + + low_memory_back = calloc(1, low_memory_size); + high_memory_back = calloc(1, high_memory_size); if (!_stricmp(opcode, "all")) { DIR *d = opendir(path); @@ -1604,12 +1687,17 @@ int main(int argc, char *argv[]) int first = 0; if (argc >= 3) { + first = -1; for (int i = 0; i < diroff; i += MAX_FILE_LEN) { if (!_stricmp(dirs + i, argv[2])) { first = i; break; } } + if (first < 0) { + printf("Couldn't find '%s'\n", argv[2]); + return 0; + } } for (int i = first; i < diroff; i += MAX_FILE_LEN) { if (test_mnemo(path, dirs + i)) { @@ -1623,4 +1711,6 @@ int main(int argc, char *argv[]) } else { test_mnemo(path, opcode); } + + return 0; } diff --git a/cputest/makefile b/cputest/makefile index 75cb52a1..ed34c980 100644 --- a/cputest/makefile +++ b/cputest/makefile @@ -5,10 +5,12 @@ NOWTIME := "\"$(shell date "+%T")\"" CC=/opt/amiga/bin/m68k-amigaos-gcc AS=/opt/amiga/bin/m68k-amigaos-as -CFLAGS = -mcrt=nix13 -O2 -m68000 -fomit-frame-pointer -msmall-code -msoft-float -DREVDATE=$(NOWDATE) -DREVTIME=$(NOWTIME) -DAMIGA +CFLAGS = -mcrt=nix13 -O2 -m68000 -fomit-frame-pointer -msmall-code -msoft-float -DREVDATE=$(NOWDATE) -DREVTIME=$(NOWTIME) -DAMIGA -DM68K LINK_CFLAGS = -mcrt=nix13 -lm -s -OBJS = main.o 68kDisass.o asm.o amiga.o +OBJS = main.o asm.o amiga.o \ + decode_ea.o globals.o opcode_handler_cpu.o opcode_handler_fpu.o \ + opcode_handler_mmu.o opcodes_cpu.o opcodes_fpu.o opcodes_mmu.o util.o all: $(OBJS) $(CC) $(LINK_CFLAGS) -o cputest $^ @@ -16,8 +18,32 @@ all: $(OBJS) main.o: main.c $(CC) $(CFLAGS) -I. -c -o $@ main.c -68kDisass.o: main.c - $(CC) $(CFLAGS) -I. -c -o $@ 68kDisass.c +decode_ea.o: adis/decode_ea.c + $(CC) $(CFLAGS) -I. -c -o $@ adis/decode_ea.c + +globals.o: adis/globals.c + $(CC) $(CFLAGS) -I. -c -o $@ adis/globals.c + +opcode_handler_cpu.o: adis/opcode_handler_cpu.c + $(CC) $(CFLAGS) -I. -c -o $@ adis/opcode_handler_cpu.c + +opcode_handler_fpu.o: adis/opcode_handler_fpu.c + $(CC) $(CFLAGS) -I. -c -o $@ adis/opcode_handler_fpu.c + +opcode_handler_mmu.o: adis/opcode_handler_mmu.c + $(CC) $(CFLAGS) -I. -c -o $@ adis/opcode_handler_mmu.c + +opcodes_cpu.o: adis/opcodes_cpu.c + $(CC) $(CFLAGS) -I. -c -o $@ adis/opcodes_cpu.c + +opcodes_fpu.o: adis/opcodes_fpu.c + $(CC) $(CFLAGS) -I. -c -o $@ adis/opcodes_fpu.c + +opcodes_mmu.o: adis/opcodes_mmu.c + $(CC) $(CFLAGS) -I. -c -o $@ adis/opcodes_mmu.c + +util.o: adis/util.c + $(CC) $(CFLAGS) -I. -c -o $@ adis/util.c asm.o: asm.S $(AS) -m68020 -o $@ asm.S diff --git a/cputest_support.cpp b/cputest_support.cpp index 1ef0dd64..5b03799c 100644 --- a/cputest_support.cpp +++ b/cputest_support.cpp @@ -6,6 +6,8 @@ #include "memory.h" #include "newcpu.h" #include "fpp.h" +#include "mmu_common.h" +#include "cpummu030.h" void my_trim(TCHAR *s) { @@ -97,4 +99,14 @@ void mmu_tt_modified(void) uae_u16 REGPARAM2 mmu_set_tc(uae_u16 tc) { return 0; -} \ No newline at end of file +} + +uae_u16 mmu030_state[3]; +int mmu030_opcode; +int mmu030_idx; +uae_u32 mmu030_disp_store[2]; +uae_u32 mmu030_fmovem_store[2]; +uae_u32 mm030_stageb_address; +struct mmu030_access mmu030_ad[MAX_MMU030_ACCESS + 1]; + +uae_u32 mmu040_move16[4]; diff --git a/disasm.cpp b/disasm.cpp index 63ba604b..af73887c 100644 --- a/disasm.cpp +++ b/disasm.cpp @@ -339,6 +339,7 @@ uaecptr ShowEA (void *f, uaecptr pc, uae_u16 opcode, int reg, amodes mode, words mode = immi; } + buffer[0] = 0; switch (mode){ case Dreg: _stprintf (buffer, _T("D%d"), reg); @@ -1678,6 +1679,7 @@ void m68k_disasm_2 (TCHAR *buf, int bufsize, uaecptr pc, uaecptr *nextpc, int cn } else if (lookup->mnemo == i_CAS) { TCHAR *p = instrname + _tcslen(instrname); _stprintf(p, _T("D%d,D%d,"), extra & 7, (extra >> 6) & 7); + pc += 2; pc = ShowEA(NULL, pc, opcode, dp->dreg, dp->dmode, dp->size, instrname, deaddr, safemode); } else if (lookup->mnemo == i_CAS2) { TCHAR *p = instrname + _tcslen(instrname); @@ -1820,6 +1822,17 @@ void m68k_disasm_2 (TCHAR *buf, int bufsize, uaecptr pc, uaecptr *nextpc, int cn pc += 2; _tcscat(instrname, _T(",")); pc = ShowEA(NULL, pc, opcode, 0, imm1, sz_word, instrname, &deaddr2, safemode); + } else if (lookup->mnemo == i_FTRAPcc) { + pc = ShowEA(NULL, pc, opcode, dp->dreg, dp->dmode, dp->size, instrname, &seaddr2, safemode); + int mode = opcode & 7; + pc += 2; + if (mode == 2) { + _tcscat(instrname, _T(",")); + pc = ShowEA(NULL, pc, opcode, 0, imm1, sz_word, instrname, NULL, safemode); + } else if (mode == 3) { + _tcscat(instrname, _T(",")); + pc = ShowEA(NULL, pc, opcode, 0, imm1, sz_long, instrname, NULL, safemode); + } } else if (lookup->mnemo == i_FPP) { TCHAR *p; int ins = extra & 0x3f; diff --git a/fpp.cpp b/fpp.cpp index 3372f60d..603ed1c6 100644 --- a/fpp.cpp +++ b/fpp.cpp @@ -677,12 +677,12 @@ uae_u32 fpp_get_fpsr (void) return regs.fpsr & 0x0ffffff8; } -static uae_u32 fpp_get_fpcr(void) +uae_u32 fpp_get_fpcr(void) { return regs.fpcr & (currprefs.fpu_model == 68040 ? 0xffff : 0xfff0); } -static void fpp_set_fpcr (uae_u32 val) +void fpp_set_fpcr (uae_u32 val) { fpp_set_mode(val); regs.fpcr = val & 0xffff; @@ -702,7 +702,7 @@ static void fpset (fpdata *fpd, uae_s32 val) fpp_from_int(fpd, val); } -static void fpp_set_fpsr (uae_u32 val) +void fpp_set_fpsr (uae_u32 val) { regs.fpsr = val; @@ -721,6 +721,16 @@ static void fpp_set_fpsr (uae_u32 val) #endif } +void fpp_set_fpiar(uae_u32 val) +{ + regs.fpiar = val; +} + +uae_u32 fpp_get_fpiar(void) +{ + return regs.fpiar; +} + bool fpu_get_constant(fpdata *fpd, int cr) { uae_u32 f[3] = { 0, 0, 0 }; @@ -2822,18 +2832,18 @@ static void fpuop_arithmetic2 (uae_u32 opcode, uae_u16 extra) } if (extra & 0x2000) { if (extra & 0x1000) - m68k_dreg (regs, opcode & 7) = fpp_get_fpcr(); + m68k_dreg(regs, opcode & 7) = fpp_get_fpcr(); if (extra & 0x0800) - m68k_dreg (regs, opcode & 7) = fpp_get_fpsr(); + m68k_dreg(regs, opcode & 7) = fpp_get_fpsr(); if ((extra & 0x0400) || !bits) - m68k_dreg (regs, opcode & 7) = regs.fpiar; + m68k_dreg(regs, opcode & 7) = fpp_get_fpiar(); } else { if (extra & 0x1000) fpp_set_fpcr(m68k_dreg (regs, opcode & 7)); if (extra & 0x0800) fpp_set_fpsr(m68k_dreg (regs, opcode & 7)); if ((extra & 0x0400) || !bits) - regs.fpiar = m68k_dreg (regs, opcode & 7); + fpp_set_fpiar(m68k_dreg (regs, opcode & 7)); } } else if ((opcode & 0x38) == 0x08) { // An @@ -2876,7 +2886,7 @@ static void fpuop_arithmetic2 (uae_u32 opcode, uae_u16 extra) if (extra & 0x0800) fpp_set_fpsr(ext[1]); if (extra & 0x0400) - regs.fpiar = ext[2]; + fpp_set_fpiar(ext[2]); } else { // immediate as destination fpu_noinst (opcode, pc); @@ -2917,7 +2927,7 @@ static void fpuop_arithmetic2 (uae_u32 opcode, uae_u16 extra) ad += 4; } if (extra & 0x0400) { - x_cp_put_long(ad, regs.fpiar); + x_cp_put_long(ad, fpp_get_fpiar()); ad += 4; } ad -= incr; @@ -2955,7 +2965,7 @@ static void fpuop_arithmetic2 (uae_u32 opcode, uae_u16 extra) ad += 4; } if (extra & 0x0400) { - regs.fpiar = x_cp_get_long (ad); + fpp_set_fpiar(x_cp_get_long (ad)); ad += 4; } if ((opcode & 0x38) == 0x18) @@ -3202,12 +3212,12 @@ void fpu_reset (void) use_long_double = false; #endif - regs.fpiar = 0; regs.fpu_exp_state = 0; regs.fp_unimp_pend = 0; get_features(); fpp_set_fpcr (0); fpp_set_fpsr (0); + fpp_set_fpiar (0); fpux_restore (NULL); // reset precision fpp_set_mode(0x00000080 | 0x00000010); diff --git a/gencpu.cpp b/gencpu.cpp index 73da02b3..aab77482 100644 --- a/gencpu.cpp +++ b/gencpu.cpp @@ -18,7 +18,7 @@ * Copyright 1995, 1996, 1997, 1998, 1999, 2000 Bernd Schmidt */ -#define CPU_TESTER 0 +#define CPU_TESTER 1 #include "sysconfig.h" #include "sysdeps.h" @@ -1989,13 +1989,13 @@ static void genastore_2 (const char *from, amodes mode, const char *reg, wordsiz if (cpu_level < 2 && (mode == PC16 || mode == PC8r)) term (); if (store_dir) { - printf ("\t%s (%sa + 2, %s);\n", dstw, to, from); + printf ("\t%s (%sa + 2, %s);\n", dstwx, to, from); check_ipl_again(); - printf ("%s (%sa, %s >> 16);\n", dstw, to, from); + printf ("%s (%sa, %s >> 16);\n", dstwx, to, from); } else { - printf ("\t%s (%sa, %s >> 16);\n", dstw, to, from); + printf ("\t%s (%sa, %s >> 16);\n", dstwx, to, from); check_ipl_again(); - printf ("\t%s (%sa + 2, %s);\n", dstw, to, from); + printf ("\t%s (%sa + 2, %s);\n", dstwx, to, from); } count_write += 2; break; @@ -2033,21 +2033,21 @@ static void genastore_2 (const char *from, amodes mode, const char *reg, wordsiz switch (size) { case sz_byte: insn_n_cycles += 4; - printf ("\t%s (%sa, %s);\n", dstb, to, from); + printf ("\t%s (%sa, %s);\n", dstbx, to, from); count_write++; break; case sz_word: insn_n_cycles += 4; if (cpu_level < 2 && (mode == PC16 || mode == PC8r)) term (); - printf ("\t%s (%sa, %s);\n", dstw, to, from); + printf ("\t%s (%sa, %s);\n", dstwx, to, from); count_write++; break; case sz_long: insn_n_cycles += 8; if (cpu_level < 2 && (mode == PC16 || mode == PC8r)) term (); - printf ("\t%s (%sa, %s);\n", dstl, to, from); + printf ("\t%s (%sa, %s);\n", dstlx, to, from); count_write += 2; break; default: @@ -3407,6 +3407,8 @@ static void gen_opcode (unsigned int opcode) if (cpu_level >= xBCD_KEEPS_V_FLAG) { if (next_cpu_level < xBCD_KEEPS_V_FLAG) next_cpu_level = xBCD_KEEPS_V_FLAG - 1; + if (cpu_level >= xBCD_KEEPS_V_FLAG && cpu_level < xBCD_KEEPS_N_FLAG) + printf("\tSET_VFLG(0);\n"); } else { printf ("\tSET_VFLG ((tmp_newv & 0x80) != 0 && (newv & 0x80) == 0);\n"); } @@ -3493,7 +3495,7 @@ static void gen_opcode (unsigned int opcode) printf ("\tif (cflg) newv += 0x60;\n"); printf ("\tSET_CFLG (cflg);\n"); duplicate_carry (0); - /* Manual says bits NV are undefined though a real 68030 doesn't change V and 68040/060 don't change both */ + /* Manual says bits NV are undefined though a real 68030 clears V and 68040/060 don't change both */ if (cpu_level >= xBCD_KEEPS_N_FLAG) { if (next_cpu_level < xBCD_KEEPS_N_FLAG) next_cpu_level = xBCD_KEEPS_N_FLAG - 1; @@ -3504,6 +3506,8 @@ static void gen_opcode (unsigned int opcode) if (cpu_level >= xBCD_KEEPS_V_FLAG) { if (next_cpu_level < xBCD_KEEPS_V_FLAG) next_cpu_level = xBCD_KEEPS_V_FLAG - 1; + if (cpu_level >= xBCD_KEEPS_V_FLAG && cpu_level < xBCD_KEEPS_N_FLAG) + printf("\tSET_VFLG(0);\n"); } else { printf ("\tSET_VFLG ((tmp_newv & 0x80) == 0 && (newv & 0x80) != 0);\n"); } @@ -3560,6 +3564,8 @@ static void gen_opcode (unsigned int opcode) if (cpu_level >= xBCD_KEEPS_V_FLAG) { if (next_cpu_level < xBCD_KEEPS_V_FLAG) next_cpu_level = xBCD_KEEPS_V_FLAG - 1; + if (cpu_level >= xBCD_KEEPS_V_FLAG && cpu_level < xBCD_KEEPS_N_FLAG) + printf("\tSET_VFLG(0);\n"); } else { printf ("\tSET_VFLG ((tmp_newv & 0x80) != 0 && (newv & 0x80) == 0);\n"); } @@ -4680,18 +4686,18 @@ bccl_not68020: genamode (curi, curi->dmode, "dstreg", curi->size, "dst", 1, 0, 0); sync_m68k_pc (); addcycles000 (4); - printf("\tsetchkundefinedflags(src, dst);\n"); printf("\tif ((uae_s32)dst < 0) {\n"); - printf("\t\tSET_NFLG (1);\n"); + printf("\t\tsetchkundefinedflags(src, dst, %d);\n", curi->size); printf("\t\tException_cpu(6);\n"); printf("\t\tgoto %s;\n", endlabelstr); printf("\t}\n"); addcycles000 (2); printf("\tif (dst > src) {\n"); - printf("\t\tSET_NFLG (0);\n"); + printf("\t\tsetchkundefinedflags(src, dst, %d);\n", curi->size); printf("\t\tException_cpu(6);\n"); printf("\t\tgoto %s;\n", endlabelstr); printf("\t}\n"); + printf("\tsetchkundefinedflags(src, dst, %d);\n", curi->size); fill_prefetch_next (); need_endlabel = 1; break; @@ -4699,7 +4705,7 @@ bccl_not68020: 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 (); - printf ("\t{uae_s32 upper,lower,reg = regs.regs[(extra >> 12) & 15];\n"); + printf ("\t{uae_u32 upper,lower,reg = regs.regs[(extra >> 12) & 15];\n"); switch (curi->size) { case sz_byte: printf ("\tlower = (uae_s32)(uae_s8)%s (dsta); upper = (uae_s32)(uae_s8)%s (dsta + 1);\n", srcb, srcb); @@ -4715,9 +4721,12 @@ bccl_not68020: default: term (); } - printf ("\tSET_ZFLG (upper == reg || lower == reg);\n"); - printf ("\tSET_CFLG_ALWAYS (lower <= upper ? reg < lower || reg > upper : reg > upper || reg < lower);\n"); - printf ("\tif ((extra & 0x800) && GET_CFLG ()) { Exception_cpu(6); goto %s; }\n}\n", endlabelstr); + printf("\tsetchk2undefinedflags(lower, upper, reg, (extra & 0x8000) ? %d : 2);\n", curi->size); + printf("\tupper -= lower;\n"); + printf("\treg -= lower;\n"); + printf("\tSET_ZFLG (upper == reg || 0 == reg);\n"); + printf("\tSET_CFLG_ALWAYS (reg > upper);\n"); + printf("\tif ((extra & 0x800) && GET_CFLG ()) { Exception_cpu(6); goto %s; }\n}\n", endlabelstr); need_endlabel = 1; break; @@ -5269,11 +5278,11 @@ bccl_not68020: int old_m68k_pc_total = m68k_pc_total; old_brace_level = n_braces; start_brace (); - printf ("\tuae_u32 src = regs.regs[(extra >> 12) & 15];\n"); genamode (curi, curi->dmode, "dstreg", curi->size, "dst", 2, 0, 0); tail_ce020_done = false; returntail(false); did_prefetch = 0; + printf("\tuae_u32 src = regs.regs[(extra >> 12) & 15];\n"); genastore_fc ("src", curi->dmode, "dstreg", curi->size, "dst"); sync_m68k_pc(); pop_braces(old_brace_level); @@ -5428,20 +5437,18 @@ bccl_not68020: break; case i_PACK: if (curi->smode == Dreg) { - printf ("\tuae_u16 val = m68k_dreg (regs, srcreg) + %s;\n", gen_nextiword (0)); - printf ("\tm68k_dreg (regs, dstreg) = (m68k_dreg (regs, dstreg) & 0xffffff00) | ((val >> 4) & 0xf0) | (val & 0xf);\n"); + printf("\tuae_u16 val = m68k_dreg (regs, srcreg) + %s;\n", gen_nextiword (0)); + printf("\tm68k_dreg (regs, dstreg) = (m68k_dreg (regs, dstreg) & 0xffffff00) | ((val >> 4) & 0xf0) | (val & 0xf);\n"); } else { printf ("\tuae_u16 val;\n"); addmmufixup ("srcreg"); - printf ("\tm68k_areg (regs, srcreg) -= areg_byteinc[srcreg];\n"); - printf ("\tval = (uae_u16)(%s (m68k_areg (regs, srcreg)) & 0xff);\n", srcb); - printf ("\tm68k_areg (regs, srcreg) -= areg_byteinc[srcreg];\n"); - printf ("\tval = val | ((uae_u16)(%s (m68k_areg (regs, srcreg)) & 0xff) << 8);\n", srcb); - printf ("\tval += %s;\n", gen_nextiword(0)); + printf("\tm68k_areg (regs, srcreg) -= 2;\n"); + printf("\tval = (uae_u16)(%s (m68k_areg (regs, srcreg)));\n", srcw); + printf("\tval += %s;\n", gen_nextiword(0)); addmmufixup ("dstreg"); - printf ("\tm68k_areg (regs, dstreg) -= areg_byteinc[dstreg];\n"); + printf("\tm68k_areg (regs, dstreg) -= areg_byteinc[dstreg];\n"); gen_set_fault_pc (false, false); - printf ("\t%s (m68k_areg (regs, dstreg),((val >> 4) & 0xf0) | (val & 0xf));\n", dstb); + printf("\t%s (m68k_areg (regs, dstreg),((val >> 4) & 0xf0) | (val & 0xf));\n", dstb); } break; case i_UNPK: @@ -5457,17 +5464,9 @@ bccl_not68020: printf ("\tval = (uae_u16)(%s (m68k_areg (regs, srcreg)) & 0xff);\n", srcb); printf ("\tval = (((val << 4) & 0xf00) | (val & 0xf)) + %s;\n", gen_nextiword (0)); addmmufixup ("dstreg"); - if (cpu_level >= 2) { - printf ("\tm68k_areg (regs, dstreg) -= 2 * areg_byteinc[dstreg];\n"); - printf ("\t%s (m68k_areg (regs, dstreg) + areg_byteinc[dstreg], val);\n", dstb); - printf ("\t%s (m68k_areg (regs, dstreg), val >> 8);\n", dstb); - } else { - printf ("\tm68k_areg (regs, dstreg) -= areg_byteinc[dstreg];\n"); - printf ("\t%s (m68k_areg (regs, dstreg),val);\n", dstb); - printf ("\tm68k_areg (regs, dstreg) -= areg_byteinc[dstreg];\n"); - gen_set_fault_pc (false, false); - printf ("\t%s (m68k_areg (regs, dstreg),val >> 8);\n", dstb); - } + printf("\tm68k_areg (regs, dstreg) -= 2;\n"); + gen_set_fault_pc(false, false); + printf("\t%s (m68k_areg (regs, dstreg), val);\n", dstw); } break; case i_TAS: diff --git a/include/fpp.h b/include/fpp.h index 49eaa348..2fbc49ea 100644 --- a/include/fpp.h +++ b/include/fpp.h @@ -25,6 +25,13 @@ extern void fpsr_set_exception(uae_u32 exception); extern void fpu_modechange(void); extern void fpu_clearstatus(void); +extern void fpp_set_fpcr(uae_u32 val); +extern void fpp_set_fpsr(uae_u32 val); +extern void fpp_set_fpiar(uae_u32 val); +extern uae_u32 fpp_get_fpsr(void); +extern uae_u32 fpp_get_fpcr(void); +extern uae_u32 fpp_get_fpiar(void); + #if defined(CPU_i386) || defined(CPU_x86_64) extern void init_fpucw_x87(void); #ifdef MSVC_LONG_DOUBLE diff --git a/include/newcpu.h b/include/newcpu.h index ab3f61c1..ebdc18a5 100644 --- a/include/newcpu.h +++ b/include/newcpu.h @@ -680,7 +680,8 @@ extern int getDivs68kCycles (uae_s32 dividend, uae_s16 divisor); extern void divbyzero_special(bool issigned, uae_s32 dst); extern void setdivuoverflowflags(uae_u32 dividend, uae_u16 divisor); extern void setdivsoverflowflags(uae_s32 dividend, uae_s16 divisor); -extern void setchkundefinedflags(uae_s16 src, uae_s16 dst); +extern void setchkundefinedflags(uae_s32 src, uae_s32 dst, int size); +extern void setchk2undefinedflags(uae_u32 lower, uae_u32 upper, uae_u32 val, int size); extern void protect_roms (bool); extern void unprotect_maprom (void); extern bool is_hardreset(void); diff --git a/newcpu.cpp b/newcpu.cpp index 84516cce..33bf3bd8 100644 --- a/newcpu.cpp +++ b/newcpu.cpp @@ -2816,7 +2816,7 @@ static void Exception_normal (int nr) if (currprefs.cpu_model >= 68040) { if (nr == 2) { if (currprefs.mmu_model) { - // 68040 mmu bus error + // 68040/060 mmu bus error for (i = 0 ; i < 7 ; i++) { m68k_areg (regs, 7) -= 4; x_put_long (m68k_areg (regs, 7), 0); @@ -2890,61 +2890,26 @@ static void Exception_normal (int nr) } } else { - m68k_areg (regs, 7) -= 4; - x_put_long (m68k_areg (regs, 7), last_fault_for_exception_3); - m68k_areg (regs, 7) -= 2; - x_put_word (m68k_areg (regs, 7), 0x2000 + vector_nr * 4); + // 68040/060 odd PC address error + Exception_build_stack_frame(last_fault_for_exception_3, currpc, 0, nr, 0x02); + used_exception_build_stack_frame = true; } } else if (currprefs.cpu_model >= 68020) { - // 68020/030 address error + // 68020/030 odd PC address error (partially implemented only) uae_u16 ssw = (sv ? 4 : 0) | (last_instructionaccess_for_exception_3 ? 2 : 1); ssw |= last_writeaccess_for_exception_3 ? 0 : 0x40; ssw |= 0x20; - for (i = 0 ; i < 36; i++) { - m68k_areg (regs, 7) -= 2; - x_put_word (m68k_areg (regs, 7), 0); - } - m68k_areg (regs, 7) -= 4; - x_put_long (m68k_areg (regs, 7), last_fault_for_exception_3); - m68k_areg (regs, 7) -= 2; - x_put_word (m68k_areg (regs, 7), 0); - m68k_areg (regs, 7) -= 2; - x_put_word (m68k_areg (regs, 7), 0); - m68k_areg (regs, 7) -= 2; - x_put_word (m68k_areg (regs, 7), 0); - m68k_areg (regs, 7) -= 2; - x_put_word (m68k_areg (regs, 7), ssw); - m68k_areg (regs, 7) -= 2; - x_put_word (m68k_areg (regs, 7), 0xb000 + vector_nr * 4); + regs.mmu_fault_addr = last_fault_for_exception_3; + Exception_build_stack_frame(oldpc, currpc, ssw, nr, 0x0a); + used_exception_build_stack_frame = true; } else { // 68010 address error (partially implemented only) uae_u16 ssw = (sv ? 4 : 0) | (last_instructionaccess_for_exception_3 ? 2 : 1); ssw |= last_writeaccess_for_exception_3 ? 0 : 0x100; ssw |= last_instructionaccess_for_exception_3 ? 0 : 0x2000; - for (i = 0; i < 15; i++) { - m68k_areg(regs, 7) -= 2; - x_put_word(m68k_areg(regs, 7), 0); - } - m68k_areg(regs, 7) -= 2; - x_put_word(m68k_areg(regs, 7), 0); // version - m68k_areg(regs, 7) -= 2; - x_put_word(m68k_areg(regs, 7), last_op_for_exception_3); // instruction input buffer - m68k_areg(regs, 7) -= 2; - x_put_word(m68k_areg(regs, 7), 0); // unused - m68k_areg(regs, 7) -= 2; - x_put_word(m68k_areg(regs, 7), 0); // data input buffer - m68k_areg(regs, 7) -= 2; - x_put_word(m68k_areg(regs, 7), 0); // unused - m68k_areg(regs, 7) -= 2; - x_put_word(m68k_areg(regs, 7), 0); // data output buffer - m68k_areg(regs, 7) -= 2; - x_put_word(m68k_areg(regs, 7), 0); // unused - m68k_areg(regs, 7) -= 4; - x_put_long(m68k_areg(regs, 7), last_addr_for_exception_3); // fault addr - m68k_areg(regs, 7) -= 2; - x_put_word(m68k_areg(regs, 7), ssw); // ssw - m68k_areg(regs, 7) -= 2; - x_put_word(m68k_areg(regs, 7), 0x8000 + vector_nr * 4); + regs.mmu_fault_addr = last_addr_for_exception_3; + Exception_build_stack_frame(oldpc, currpc, ssw, nr, 0x08); + used_exception_build_stack_frame = true; } write_log (_T("Exception %d (%x) at %x -> %x!\n"), nr, regs.instruction_pc, currpc, get_long_debug (regs.vbr + 4 * vector_nr)); } else if (regs.m && interrupt) { /* M + Interrupt */ @@ -2970,7 +2935,7 @@ static void Exception_normal (int nr) add_approximate_exception_cycles(nr); nextpc = m68k_getpc (); if (nr == 2 || nr == 3) { - // 68000 address error + // 68000 bus error/address error uae_u16 mode = (sv ? 4 : 0) | (last_instructionaccess_for_exception_3 ? 2 : 1); mode |= last_writeaccess_for_exception_3 ? 0 : 16; mode |= last_notinstruction_for_exception_3 ? 8 : 0; diff --git a/newcpu_common.cpp b/newcpu_common.cpp index c29c69c3..bbce3b5b 100644 --- a/newcpu_common.cpp +++ b/newcpu_common.cpp @@ -762,7 +762,7 @@ int getDivs68kCycles (uae_s32 dividend, uae_s16 divisor) /* DIV divide by zero * * 68000 Signed: NVC=0 Z=1. Unsigned: VC=0 N=(dst>>16)<0 Z=(dst>>16)==0 - * 68020 and 68030: Signed: Z=1 NVC=0. Unsigned: V=1, N=(dst>>16)<0 Z=(dst>>16)==0, C=0. + * 68020 and 68030: Signed: Z=1 NC=0. V=? (sometimes random!) Unsigned: V=1, N=(dst>>16)<0 Z=(dst>>16)==0, C=0. * 68040/68060 C=0. * */ @@ -858,14 +858,66 @@ void setdivsoverflowflags(uae_s32 dividend, uae_s16 divisor) /* * CHK.W undefined flags * - * 68000: CV=0, Z if dst==0. + * 68000: CV=0. Z: dst==0. N: dst < 0. !N: dst > src. + * 68020: Z: dst==0. N: dst < 0. V: src-dst overflow. C: if dst < 0: (dst > src || src >= 0), if dst > src: (src >= 0). * */ -void setchkundefinedflags(uae_s16 src, uae_s16 dst) +void setchkundefinedflags(uae_s32 src, uae_s32 dst, int size) { CLEAR_CZNV(); - if (dst == 0) - SET_ZFLG(1); + if (currprefs.cpu_model < 68020) { + if (dst == 0) + SET_ZFLG(1); + if (dst < 0) + SET_NFLG(1); + else if (dst > src) + SET_NFLG(0); + } else if (currprefs.cpu_model == 68020 || currprefs.cpu_model == 68030) { + if (dst == 0) + SET_ZFLG(1); + SET_NFLG(dst < 0); + if (dst < 0 || dst > src) { + if (size == sz_word) { + int flgs = ((uae_s16)(dst)) < 0; + int flgo = ((uae_s16)(src)) < 0; + uae_s16 val = (uae_s16)src - (uae_s16)dst; + int flgn = val < 0; + SET_VFLG((flgs ^ flgo) & (flgn ^ flgo)); + } else { + int flgs = dst < 0; + int flgo = src < 0; + uae_s32 val = src - dst; + int flgn = val < 0; + SET_VFLG((flgs ^ flgo) & (flgn ^ flgo)); + } + if (dst < 0) { + SET_CFLG(dst > src || src >= 0); + } else { + SET_CFLG(src >= 0); + } + } + } +} + +void setchk2undefinedflags(uae_u32 lower, uae_u32 upper, uae_u32 val, int size) +{ + uae_u32 nmask; + if (size == sz_byte) + nmask = 0x80; + else if (size == sz_word) + nmask = 0x8000; + else + nmask = 0x80000000; + + SET_NFLG(0); + if ((upper & nmask) && val > upper) { + SET_NFLG(1); + } else if (!(upper & nmask) && val > upper && val < nmask) { + SET_NFLG(1); + } else if (val < lower) { + SET_NFLG(1); + } + SET_VFLG(0); } #ifndef CPUEMU_68000_ONLY @@ -896,6 +948,14 @@ STATIC_INLINE int div_unsigned (uae_u32 src_hi, uae_u32 src_lo, uae_u32 div, uae } #endif +static void divl_overflow(void) +{ + SET_VFLG(1); + SET_NFLG(1); + SET_CFLG(0); + SET_ZFLG(0); +} + bool m68k_divl (uae_u32 opcode, uae_u32 src, uae_u16 extra) { if ((extra & 0x400) && currprefs.int_no_unimplemented && currprefs.cpu_model == 68060) { @@ -903,7 +963,7 @@ bool m68k_divl (uae_u32 opcode, uae_u32 src, uae_u16 extra) return false; } if (src == 0) { - Exception_cpu (5); + Exception_cpu(5); return false; } #if defined (uae_s64) @@ -918,18 +978,14 @@ bool m68k_divl (uae_u32 opcode, uae_u32 src, uae_u16 extra) } if ((uae_u64)a == 0x8000000000000000UL && src == ~0u) { - SET_VFLG (1); - SET_NFLG (1); - SET_CFLG (0); + divl_overflow(); } else { rem = a % (uae_s64)(uae_s32)src; quot = a / (uae_s64)(uae_s32)src; if ((quot & UVAL64 (0xffffffff80000000)) != 0 && (quot & UVAL64 (0xffffffff80000000)) != UVAL64 (0xffffffff80000000)) { - SET_VFLG (1); - SET_NFLG (1); - SET_CFLG (0); + divl_overflow(); } else { if (((uae_s32)rem < 0) != ((uae_s64)a < 0)) rem = -rem; SET_VFLG (0); @@ -952,9 +1008,7 @@ bool m68k_divl (uae_u32 opcode, uae_u32 src, uae_u16 extra) rem = a % (uae_u64)src; quot = a / (uae_u64)src; if (quot > 0xffffffffu) { - SET_VFLG (1); - SET_NFLG (1); - SET_CFLG (0); + divl_overflow(); } else { SET_VFLG (0); SET_CFLG (0); @@ -986,9 +1040,7 @@ bool m68k_divl (uae_u32 opcode, uae_u32 src, uae_u16 extra) if ((uae_s32)src < 0) src = -src; if (div_unsigned (hi, lo, src, ", &rem) || (sign & 0x80000000) ? quot > 0x80000000 : quot > 0x7fffffff) { - SET_VFLG (1); - SET_NFLG (1); - SET_CFLG (0); + divl_overflow(); } else { if (sign & 0x80000000) quot = -quot; if (((uae_s32)rem < 0) != (save_high < 0)) rem = -rem; @@ -1009,9 +1061,7 @@ bool m68k_divl (uae_u32 opcode, uae_u32 src, uae_u16 extra) hi = (uae_u32)m68k_dreg (regs, extra & 7); } if (div_unsigned (hi, lo, src, ", &rem)) { - SET_VFLG (1); - SET_NFLG (1); - SET_CFLG (0); + divl_overflow(); } else { SET_VFLG (0); SET_CFLG (0); @@ -1188,7 +1238,13 @@ void Exception_build_stack_frame(uae_u32 oldpc, uae_u32 currpc, uae_u32 ssw, int m68k_areg(regs, 7) -= 4; x_put_long(m68k_areg(regs, 7), regs.fp_ea); break; -#ifndef CPU_TESTER + case 0x4: // floating point unimplemented stack frame (68LC040, 68EC040) + // or 68060 bus access fault stack frame + m68k_areg(regs, 7) -= 4; + x_put_long(m68k_areg(regs, 7), ssw); + m68k_areg(regs, 7) -= 4; + x_put_long(m68k_areg(regs, 7), oldpc); + break; case 0x7: // access error stack frame (68040) for (i = 3; i >= 0; i--) { @@ -1225,7 +1281,30 @@ void Exception_build_stack_frame(uae_u32 oldpc, uae_u32 currpc, uae_u32 ssw, int m68k_areg(regs, 7) -= 4; x_put_long(m68k_areg(regs, 7), regs.mmu_effective_addr); break; -#endif + case 0x8: // address error (68010) + for (i = 0; i < 15; i++) { + m68k_areg(regs, 7) -= 2; + x_put_word(m68k_areg(regs, 7), 0); + } + m68k_areg(regs, 7) -= 2; + x_put_word(m68k_areg(regs, 7), 0); // version + m68k_areg(regs, 7) -= 2; + x_put_word(m68k_areg(regs, 7), regs.opcode); // instruction input buffer + m68k_areg(regs, 7) -= 2; + x_put_word(m68k_areg(regs, 7), 0); // unused + m68k_areg(regs, 7) -= 2; + x_put_word(m68k_areg(regs, 7), 0); // data input buffer + m68k_areg(regs, 7) -= 2; + x_put_word(m68k_areg(regs, 7), 0); // unused + m68k_areg(regs, 7) -= 2; + x_put_word(m68k_areg(regs, 7), 0); // data output buffer + m68k_areg(regs, 7) -= 2; + x_put_word(m68k_areg(regs, 7), 0); // unused + m68k_areg(regs, 7) -= 4; + x_put_long(m68k_areg(regs, 7), regs.mmu_fault_addr); // fault addr + m68k_areg(regs, 7) -= 2; + x_put_word(m68k_areg(regs, 7), ssw); // ssw + break; case 0x9: // coprocessor mid-instruction stack frame (68020, 68030) m68k_areg(regs, 7) -= 4; x_put_long(m68k_areg(regs, 7), regs.fp_ea); @@ -1234,17 +1313,6 @@ void Exception_build_stack_frame(uae_u32 oldpc, uae_u32 currpc, uae_u32 ssw, int m68k_areg(regs, 7) -= 4; x_put_long(m68k_areg(regs, 7), oldpc); break; - case 0x8: // bus and address error stack frame (68010) - write_log(_T("Exception stack frame format %X not implemented\n"), format); - return; - case 0x4: // floating point unimplemented stack frame (68LC040, 68EC040) - // or 68060 bus access fault stack frame - m68k_areg(regs, 7) -= 4; - x_put_long(m68k_areg(regs, 7), ssw); - m68k_areg(regs, 7) -= 4; - x_put_long(m68k_areg(regs, 7), oldpc); - break; -#ifndef CPU_TESTER case 0xB: // long bus cycle fault stack frame (68020, 68030) // Store state information to internal register space #if MMU030_DEBUG @@ -1343,7 +1411,6 @@ void Exception_build_stack_frame(uae_u32 oldpc, uae_u32 currpc, uae_u32 ssw, int m68k_areg(regs, 7) -= 2; x_put_word(m68k_areg(regs, 7), regs.wb2_address); // = mmu030_state[1]); break; -#endif default: write_log(_T("Unknown exception stack frame format: %X\n"), format); return; diff --git a/readcpu.cpp b/readcpu.cpp index 0f0b21e8..eb9f1856 100644 --- a/readcpu.cpp +++ b/readcpu.cpp @@ -128,7 +128,6 @@ struct mnemolookup lookuptab[] = { { i_FScc, _T("FScc"), NULL, 0 }, { i_FTRAPcc, _T("FTRAPcc"), NULL, 0 }, { i_FBcc, _T("FBcc"), NULL, 0 }, - { i_FBcc, _T("FBcc"), NULL, 0 }, { i_FSAVE, _T("FSAVE"), NULL, 0 }, { i_FRESTORE, _T("FRESTORE"), NULL, 0 }, -- 2.47.3