--- previous/src/cpu/readcpu.c 2018/04/24 19:25:47 1.1 +++ previous/src/cpu/readcpu.c 2018/04/24 19:33:34 1.1.1.4 @@ -1,10 +1,10 @@ /* -* UAE - The Un*x Amiga Emulator -* -* Read 68000 CPU specs from file "table68k" -* -* Copyright 1995,1996 Bernd Schmidt -*/ + * UAE - The Un*x Amiga Emulator + * + * Read 68000 CPU specs from file "table68k" + * + * Copyright 1995,1996 Bernd Schmidt + */ #include "sysconfig.h" #include "sysdeps.h" @@ -16,866 +16,860 @@ int nr_cpuop_funcs; struct mnemolookup lookuptab[] = { - { i_ILLG, "ILLEGAL" , ""}, - { i_OR, "OR" , "" }, - { i_CHK, "CHK" , "" }, - { i_CHK2, "CHK2" , "" }, - { i_AND, "AND" , "" }, - { i_EOR, "EOR" , "" }, - { i_ORSR, "ORSR" , "" }, - { i_ANDSR, "ANDSR" , "" }, - { i_EORSR, "EORSR" , "" }, - { i_SUB, "SUB" , "" }, - { i_SUBA, "SUBA" , "" }, - { i_SUBX, "SUBX" , "" }, - { i_SBCD, "SBCD" , "" }, - { i_ADD, "ADD" , "" }, - { i_ADDA, "ADDA" , "" }, - { i_ADDX, "ADDX" , "" }, - { i_ABCD, "ABCD" , "" }, - { i_NEG, "NEG" , ""}, - { i_NEGX, "NEGX" , "" }, - { i_NBCD, "NBCD" , "" }, - { i_CLR, "CLR" , "" }, - { i_NOT, "NOT" , "" }, - { i_TST, "TST" , "" }, - { i_BTST, "BTST" , "" }, - { i_BCHG, "BCHG" , "" }, - { i_BCLR, "BCLR" , ""}, - { i_BSET, "BSET" , ""}, - { i_CMP, "CMP" , "" }, - { i_CMPM, "CMPM" , ""}, - { i_CMPA, "CMPA" , ""}, - { i_MVPRM, "MVPRM" , "" }, - { i_MVPMR, "MVPMR" , "" }, - { i_MOVE, "MOVE" , "" }, - { i_MOVEA, "MOVEA" , "" }, - { i_MVSR2, "MVSR2" , "" }, - { i_MV2SR, "MV2SR" , "" }, - { i_SWAP, "SWAP" , "" }, - { i_EXG, "EXG" , "" }, - { i_EXT, "EXT" , ""}, - { i_MVMEL, "MVMEL", "MOVEM" }, - { i_MVMLE, "MVMLE", "MOVEM" }, - { i_TRAP, "TRAP" , "" }, - { i_MVR2USP, "MVR2USP" , "" }, - { i_MVUSP2R, "MVUSP2R" , ""}, - { i_NOP, "NOP" , "" }, - { i_RESET, "RESET" , "" }, - { i_RTE, "RTE" , "" }, - { i_RTD, "RTD" , "" }, - { i_LINK, "LINK" , "" }, - { i_UNLK, "UNLK" , "" }, - { i_RTS, "RTS" , "" }, - { i_STOP, "STOP" , "" }, - { i_TRAPV, "TRAPV" , ""}, - { i_RTR, "RTR" , "" }, - { i_JSR, "JSR" , "" }, - { i_JMP, "JMP" , ""}, - { i_BSR, "BSR" , ""}, - { i_Bcc, "Bcc" , ""}, - { i_LEA, "LEA" , ""}, - { i_PEA, "PEA" , ""}, - { i_DBcc, "DBcc" , "" }, - { i_Scc, "Scc" , "" }, - { i_DIVU, "DIVU" , "" }, - { i_DIVS, "DIVS" , ""}, - { i_MULU, "MULU" , "" }, - { i_MULS, "MULS" , "" }, - { i_ASR, "ASR" , "" }, - { i_ASL, "ASL" , ""}, - { i_LSR, "LSR" , ""}, - { i_LSL, "LSL" , ""}, - { i_ROL, "ROL" , ""}, - { i_ROR, "ROR" , ""}, - { i_ROXL, "ROXL" , "" }, - { i_ROXR, "ROXR" , ""}, - { i_ASRW, "ASRW" , "" }, - { i_ASLW, "ASLW" , ""}, - { i_LSRW, "LSRW" , "" }, - { i_LSLW, "LSLW" , ""}, - { i_ROLW, "ROLW" , ""}, - { i_RORW, "RORW" , ""}, - { i_ROXLW, "ROXLW" , "" }, - { i_ROXRW, "ROXRW" , ""}, - - { i_MOVE2C, "MOVE2C", "MOVEC" }, - { i_MOVEC2, "MOVEC2", "MOVEC" }, - { i_CAS, "CAS" , "" }, - { i_CAS2, "CAS2" , "" }, - { i_MULL, "MULL" , "" }, - { i_DIVL, "DIVL" , ""}, - { i_BFTST, "BFTST" , ""}, - { i_BFEXTU, "BFEXTU" , ""}, - { i_BFCHG, "BFCHG" , "" }, - { i_BFEXTS, "BFEXTS" , "" }, - { i_BFCLR, "BFCLR" , ""}, - { i_BFFFO, "BFFFO" , "" }, - { i_BFSET, "BFSET" , ""}, - { i_BFINS, "BFINS" , ""}, - { i_PACK, "PACK" , ""}, - { i_UNPK, "UNPK" , ""}, - { i_TAS, "TAS" , ""}, - { i_BKPT, "BKPT" , ""}, - { i_CALLM, "CALLM" , ""}, - { i_RTM, "RTM" , ""}, - { i_TRAPcc, "TRAPcc" , ""}, - { i_MOVES, "MOVES" , ""}, - { i_FPP, "FPP" , ""}, - { i_FDBcc, "FDBcc" , ""}, - { i_FScc, "FScc" , ""}, - { i_FTRAPcc, "FTRAPcc" , "" }, - { i_FBcc, "FBcc" , ""}, - { i_FBcc, "FBcc" , ""}, - { i_FSAVE, "FSAVE" , ""}, - { i_FRESTORE, "FRESTORE" , ""}, - - { i_CINVL, "CINVL" , ""}, - { i_CINVP, "CINVP" , "" }, - { i_CINVA, "CINVA" , ""}, - { i_CPUSHL, "CPUSHL" , ""}, - { i_CPUSHP, "CPUSHP" , "" }, - { i_CPUSHA, "CPUSHA" , "" }, - { i_MOVE16, "MOVE16" , ""}, - - { i_MMUOP030, "MMUOP030" , "" }, - { i_PFLUSHN, "PFLUSHN" , "" }, - { i_PFLUSH, "PFLUSH" , ""}, - { i_PFLUSHAN, "PFLUSHAN" , ""}, - { i_PFLUSHA, "PFLUSHA" , ""}, - - { i_PLPAR, "PLPAR" , ""}, - { i_PLPAW, "PLPAW" , ""}, - { i_PTESTR, "PTESTR" , ""}, - { i_PTESTW, "PTESTW" , ""}, - - { i_LPSTOP, "LPSTOP" , ""}, - { i_ILLG, "" , ""}, + { i_ILLG, _T("ILLEGAL"), NULL, 0 }, + { i_OR, _T("OR"), NULL, 1 }, + { i_CHK, _T("CHK"), NULL, 0 }, + { i_CHK2, _T("CHK2"), NULL, 0 }, + { i_AND, _T("AND"), NULL, 1 }, + { i_EOR, _T("EOR"), NULL, 1 }, + { i_ORSR, _T("ORSR"), NULL, 0 }, + { i_ANDSR, _T("ANDSR"), NULL, 0 }, + { i_EORSR, _T("EORSR"), NULL, 0 }, + { i_SUB, _T("SUB"), NULL, 1 }, + { i_SUBA, _T("SUBA"), NULL, 1 }, + { i_SUBX, _T("SUBX"), NULL, 0 }, + { i_SBCD, _T("SBCD"), NULL, 0 }, + { i_ADD, _T("ADD"), NULL, 1 }, + { i_ADDA, _T("ADDA"), NULL, 1 }, + { i_ADDX, _T("ADDX"), NULL, 0 }, + { i_ABCD, _T("ABCD"), NULL, 0 }, + { i_NEG, _T("NEG"), NULL, 1 }, + { i_NEGX, _T("NEGX"), NULL, 1 }, + { i_NBCD, _T("NBCD"), NULL, 0 }, + { i_CLR, _T("CLR"), NULL, 0 }, + { i_NOT, _T("NOT"), NULL, 1 }, + { i_TST, _T("TST"), NULL, 1 }, + { i_BTST, _T("BTST"), NULL, 1 }, + { i_BCHG, _T("BCHG"), NULL, 1 }, + { i_BCLR, _T("BCLR"), NULL, 1 }, + { i_BSET, _T("BSET"), NULL, 1 }, + { i_CMP, _T("CMP"), NULL, 1 }, + { i_CMPM, _T("CMPM"), NULL, 1 }, + { i_CMPA, _T("CMPA"), NULL, 1 }, + { i_MVPRM, _T("MVPRM"), NULL, 0 }, + { i_MVPMR, _T("MVPMR"), NULL, 0 }, + { i_MOVE, _T("MOVE"), NULL, 1 }, + { i_MOVEA, _T("MOVEA"), NULL, 1 }, + { i_MVSR2, _T("MVSR2"), NULL, 0 }, + { i_MV2SR, _T("MV2SR"), NULL, 0 }, + { i_SWAP, _T("SWAP"), NULL, 0 }, + { i_EXG, _T("EXG"), NULL, 0 }, + { i_EXT, _T("EXT"), NULL, 0 }, + { i_MVMEL, _T("MVMEL"), _T("MOVEM"), 0 }, + { i_MVMLE, _T("MVMLE"), _T("MOVEM"), 0 }, + { i_TRAP, _T("TRAP"), NULL, 0 }, + { i_MVR2USP, _T("MVR2USP"), NULL, 0 }, + { i_MVUSP2R, _T("MVUSP2R"), NULL, 0 }, + { i_NOP, _T("NOP"), NULL, 0 }, + { i_RESET, _T("RESET"), NULL, 0 }, + { i_RTE, _T("RTE"), NULL, 0 }, + { i_RTD, _T("RTD"), NULL, 0 }, + { i_LINK, _T("LINK"), NULL, 0 }, + { i_UNLK, _T("UNLK"), NULL, 0 }, + { i_RTS, _T("RTS"), NULL, 0 }, + { i_STOP, _T("STOP"), NULL, 0 }, + { i_TRAPV, _T("TRAPV"), NULL, 0 }, + { i_RTR, _T("RTR"), NULL, 0 }, + { i_JSR, _T("JSR"), NULL, 0 }, + { i_JMP, _T("JMP"), NULL, 0 }, + { i_BSR, _T("BSR"), NULL, 0 }, + { i_Bcc, _T("Bcc"), NULL, 0 }, + { i_LEA, _T("LEA"), NULL, 0 }, + { i_PEA, _T("PEA"), NULL, 0 }, + { i_DBcc, _T("DBcc"), NULL, 0 }, + { i_Scc, _T("Scc"), NULL, 1 }, + { i_DIVU, _T("DIVU"), NULL, 1 }, + { i_DIVS, _T("DIVS"), NULL, 1 }, + { i_MULU, _T("MULU"), NULL, 1 }, + { i_MULS, _T("MULS"), NULL, 1 }, + { i_ASR, _T("ASR"), NULL, }, + { i_ASL, _T("ASL"), NULL, 0 }, + { i_LSR, _T("LSR"), NULL, 0 }, + { i_LSL, _T("LSL"), NULL, 0 }, + { i_ROL, _T("ROL"), NULL, 0 }, + { i_ROR, _T("ROR"), NULL, 0 }, + { i_ROXL, _T("ROXL"), NULL, 1 }, + { i_ROXR, _T("ROXR"), NULL, 1 }, + { i_ASRW, _T("ASRW"), NULL, 1 }, + { i_ASLW, _T("ASLW"), NULL, 1 }, + { i_LSRW, _T("LSRW"), NULL, 1 }, + { i_LSLW, _T("LSLW"), NULL, 1 }, + { i_ROLW, _T("ROLW"), NULL, 1 }, + { i_RORW, _T("RORW"), NULL, 1 }, + { i_ROXLW, _T("ROXLW"), NULL, 1 }, + { i_ROXRW, _T("ROXRW"), NULL, 1 }, + + { i_MOVE2C, _T("MOVE2C"), _T("MOVEC"), 0 }, + { i_MOVEC2, _T("MOVEC2"), _T("MOVEC"), 0 }, + { i_CAS, _T("CAS"), NULL, 1 }, + { i_CAS2, _T("CAS2"), NULL, 1 }, + { i_MULL, _T("MULL"), NULL, 0 }, + { i_DIVL, _T("DIVL"), NULL, 0 }, + { i_BFTST, _T("BFTST"), NULL, 0 }, + { i_BFEXTU, _T("BFEXTU"), NULL, 0 }, + { i_BFCHG, _T("BFCHG"), NULL, 0 }, + { i_BFEXTS, _T("BFEXTS"), NULL, 0 }, + { i_BFCLR, _T("BFCLR"), NULL, 0 }, + { i_BFFFO, _T("BFFFO"), NULL, 0 }, + { i_BFSET, _T("BFSET"), NULL, 0 }, + { i_BFINS, _T("BFINS"), NULL, 0 }, + { i_PACK, _T("PACK"), NULL, 0 }, + { i_UNPK, _T("UNPK"), NULL, 0 }, + { i_TAS, _T("TAS"), NULL, 1 }, + { i_BKPT, _T("BKPT"), NULL, 0 }, + { i_CALLM, _T("CALLM"), NULL, 0 }, + { i_RTM, _T("RTM"), NULL, 0 }, + { i_TRAPcc, _T("TRAPcc"), NULL, 0 }, + { i_MOVES, _T("MOVES"), NULL, 1 }, + { i_FPP, _T("FPP"), NULL, 0 }, + { i_FDBcc, _T("FDBcc"), NULL, 0 }, + { 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 }, + + { i_CINVL, _T("CINVL"), NULL, 0 }, + { i_CINVP, _T("CINVP"), NULL, 0 }, + { i_CINVA, _T("CINVA"), NULL, 0 }, + { i_CPUSHL, _T("CPUSHL"), NULL, 0 }, + { i_CPUSHP, _T("CPUSHP"), NULL, 0 }, + { i_CPUSHA, _T("CPUSHA"), NULL, 0 }, + { i_MOVE16, _T("MOVE16"), NULL, 0 }, + + { i_MMUOP030, _T("MMUOP030"), NULL, 0 }, + { i_PFLUSHN, _T("PFLUSHN"), NULL, 0 }, + { i_PFLUSH, _T("PFLUSH"), NULL, 0 }, + { i_PFLUSHAN, _T("PFLUSHAN"), NULL, 0 }, + { i_PFLUSHA, _T("PFLUSHA"), NULL, 0 }, + + { i_PLPAR, _T("PLPAR"), NULL, 0 }, + { i_PLPAW, _T("PLPAW"), NULL, 0 }, + { i_PTESTR, _T("PTESTR"), NULL, 0 }, + { i_PTESTW, _T("PTESTW"), NULL, 0 }, + + { i_LPSTOP, _T("LPSTOP"), NULL, 0 }, + { i_ILLG, _T(""), NULL, 0 }, }; struct instr *table68k; -static int specialcase (uae_u16 opcode, int cpu_lev) -{ - int mode = (opcode >> 3) & 7; - int reg = opcode & 7; - - if (cpu_lev >= 2) - return cpu_lev; - /* TST.W A0, TST.L A0, TST.x (d16,PC) and TST.x (d8,PC,Xn) are 68020+ only */ - if ((opcode & 0xff00) == 0x4a00) { - if (mode == 7 && (reg == 4 || reg == 2 || reg == 3)) - return 2; - if (mode == 1) /* Ax */ - return 2; - } - /* CMPI.W #x,(d16,PC) and CMPI.W #x,(d8,PC,Xn) are 68020+ only */ - if ((opcode & 0xff00) == 0x0c00) { - if (mode == 7 && (reg == 2 || reg == 3)) - return 2; - } - return cpu_lev; -} - static amodes mode_from_str (const TCHAR *str) { - if (_tcsncmp (str, "Dreg", 4) == 0) return Dreg; - if (_tcsncmp (str, "Areg", 4) == 0) return Areg; - if (_tcsncmp (str, "Aind", 4) == 0) return Aind; - if (_tcsncmp (str, "Apdi", 4) == 0) return Apdi; - if (_tcsncmp (str, "Aipi", 4) == 0) return Aipi; - if (_tcsncmp (str, "Ad16", 4) == 0) return Ad16; - if (_tcsncmp (str, "Ad8r", 4) == 0) return Ad8r; - if (_tcsncmp (str, "absw", 4) == 0) return absw; - if (_tcsncmp (str, "absl", 4) == 0) return absl; - if (_tcsncmp (str, "PC16", 4) == 0) return PC16; - if (_tcsncmp (str, "PC8r", 4) == 0) return PC8r; - if (_tcsncmp (str, "Immd", 4) == 0) return imm; - abort (); - return 0; + if (_tcsncmp (str, _T("Dreg"), 4) == 0) return Dreg; + if (_tcsncmp (str, _T("Areg"), 4) == 0) return Areg; + if (_tcsncmp (str, _T("Aind"), 4) == 0) return Aind; + if (_tcsncmp (str, _T("Apdi"), 4) == 0) return Apdi; + if (_tcsncmp (str, _T("Aipi"), 4) == 0) return Aipi; + if (_tcsncmp (str, _T("Ad16"), 4) == 0) return Ad16; + if (_tcsncmp (str, _T("Ad8r"), 4) == 0) return Ad8r; + if (_tcsncmp (str, _T("absw"), 4) == 0) return absw; + if (_tcsncmp (str, _T("absl"), 4) == 0) return absl; + if (_tcsncmp (str, _T("PC16"), 4) == 0) return PC16; + if (_tcsncmp (str, _T("PC8r"), 4) == 0) return PC8r; + if (_tcsncmp (str, _T("Immd"), 4) == 0) return imm; + abort (); + return 0; } STATIC_INLINE amodes mode_from_mr (int mode, int reg) { - switch (mode) { - case 0: return Dreg; - case 1: return Areg; - case 2: return Aind; - case 3: return Aipi; - case 4: return Apdi; - case 5: return Ad16; - case 6: return Ad8r; - case 7: - switch (reg) { - case 0: return absw; - case 1: return absl; - case 2: return PC16; - case 3: return PC8r; - case 4: return imm; - case 5: - case 6: - case 7: return am_illg; - } - } - abort (); - return 0; + switch (mode) { + case 0: return Dreg; + case 1: return Areg; + case 2: return Aind; + case 3: return Aipi; + case 4: return Apdi; + case 5: return Ad16; + case 6: return Ad8r; + case 7: + switch (reg) { + case 0: return absw; + case 1: return absl; + case 2: return PC16; + case 3: return PC8r; + case 4: return imm; + case 5: + case 6: + case 7: return am_illg; + } + } + abort (); + return 0; } static void build_insn (int insn) { - int find = -1; - int variants; - int isjmp = 0; - struct instr_def id; - const TCHAR *opcstr; - int i; - - int flaglive = 0, flagdead = 0; - - id = defs68k[insn]; - - /* Note: We treat anything with unknown flags as a jump. That - is overkill, but "the programmer" was lazy quite often, and - *this* programmer can't be bothered to work out what can and - can't trap. Usually, this will be overwritten with the gencomp - based information, anyway. */ - - for (i = 0; i < 5; i++) { - switch (id.flaginfo[i].flagset){ - case fa_unset: break; - case fa_isjmp: isjmp = 1; break; - case fa_isbranch: isjmp = 1; break; - case fa_zero: flagdead |= 1 << i; break; - case fa_one: flagdead |= 1 << i; break; - case fa_dontcare: flagdead |= 1 << i; break; - case fa_unknown: isjmp = 1; flagdead = -1; goto out1; - case fa_set: flagdead |= 1 << i; break; - } - } - + int find = -1; + int variants; + int isjmp = 0; + struct instr_def id; + const TCHAR *opcstr; + int i; + + int flaglive = 0, flagdead = 0; + + id = defs68k[insn]; + + /* Note: We treat anything with unknown flags as a jump. That + is overkill, but "the programmer" was lazy quite often, and + *this* programmer can't be bothered to work out what can and + can't trap. Usually, this will be overwritten with the gencomp + based information, anyway. */ + + for (i = 0; i < 5; i++) { + switch (id.flaginfo[i].flagset){ + case fa_unset: break; + case fa_isjmp: isjmp = 1; break; + case fa_isbranch: isjmp = 1; break; + case fa_zero: flagdead |= 1 << i; break; + case fa_one: flagdead |= 1 << i; break; + case fa_dontcare: flagdead |= 1 << i; break; + case fa_unknown: isjmp = 1; flagdead = -1; goto out1; + case fa_set: flagdead |= 1 << i; break; + } + } + out1: - for (i = 0; i < 5; i++) { - switch (id.flaginfo[i].flaguse) { - case fu_unused: break; - case fu_isjmp: isjmp = 1; flaglive |= 1 << i; break; - case fu_maybecc: isjmp = 1; flaglive |= 1 << i; break; - case fu_unknown: isjmp = 1; flaglive |= 1 << i; break; - case fu_used: flaglive |= 1 << i; break; - } - } - - opcstr = id.opcstr; - for (variants = 0; variants < (1 << id.n_variable); variants++) { - int bitcnt[lastbit]; - int bitval[lastbit]; - int bitpos[lastbit]; - int i; - uae_u16 opc = id.bits; - uae_u16 msk, vmsk; - int pos = 0; - int mnp = 0; - int bitno = 0; - TCHAR mnemonic[10]; - - wordsizes sz = sz_long; - int srcgather = 0, dstgather = 0; - int usesrc = 0, usedst = 0; - int srctype = 0; - int srcpos = -1, dstpos = -1; - - amodes srcmode = am_unknown, destmode = am_unknown; - int srcreg = -1, destreg = -1; - - for (i = 0; i < lastbit; i++) - bitcnt[i] = bitval[i] = 0; - - vmsk = 1 << id.n_variable; - - for (i = 0, msk = 0x8000; i < 16; i++, msk >>= 1) { - if (!(msk & id.mask)) { - int currbit = id.bitpos[bitno++]; - int bit_set; - vmsk >>= 1; - bit_set = variants & vmsk ? 1 : 0; - if (bit_set) - opc |= msk; - bitpos[currbit] = 15 - i; - bitcnt[currbit]++; - bitval[currbit] <<= 1; - bitval[currbit] |= bit_set; - } - } - - if (bitval[bitj] == 0) bitval[bitj] = 8; - /* first check whether this one does not match after all */ - if (bitval[bitz] == 3 || bitval[bitC] == 1) - continue; - if (bitcnt[bitI] && (bitval[bitI] == 0x00 || bitval[bitI] == 0xff)) - continue; - - /* bitI and bitC get copied to biti and bitc */ - if (bitcnt[bitI]) { - bitval[biti] = bitval[bitI]; bitpos[biti] = bitpos[bitI]; - } - if (bitcnt[bitC]) - bitval[bitc] = bitval[bitC]; - - pos = 0; - while (opcstr[pos] && !_istspace(opcstr[pos])) { - if (opcstr[pos] == '.') { - pos++; - switch (opcstr[pos]) { - - case 'B': sz = sz_byte; break; - case 'W': sz = sz_word; break; - case 'L': sz = sz_long; break; - case 'z': - switch (bitval[bitz]) { - case 0: sz = sz_byte; break; - case 1: sz = sz_word; break; - case 2: sz = sz_long; break; - default: abort(); - } - break; - default: abort(); - } - } else { - mnemonic[mnp] = opcstr[pos]; - if (mnemonic[mnp] == 'f') { - find = -1; - switch (bitval[bitf]) { - case 0: mnemonic[mnp] = 'R'; break; - case 1: mnemonic[mnp] = 'L'; break; - default: abort(); - } - } - mnp++; - } - pos++; - } - mnemonic[mnp] = 0; - - /* now, we have read the mnemonic and the size */ - while (opcstr[pos] && _istspace(opcstr[pos])) - pos++; - - /* A goto a day keeps the D******a away. */ - if (opcstr[pos] == 0) - goto endofline; - - /* parse the source address */ - usesrc = 1; - switch (opcstr[pos++]) { - case 'D': - srcmode = Dreg; - switch (opcstr[pos++]) { - case 'r': srcreg = bitval[bitr]; srcgather = 1; srcpos = bitpos[bitr]; break; - case 'R': srcreg = bitval[bitR]; srcgather = 1; srcpos = bitpos[bitR]; break; - default: abort(); - } - break; - case 'A': - srcmode = Areg; - switch (opcstr[pos++]) { - case 'r': srcreg = bitval[bitr]; srcgather = 1; srcpos = bitpos[bitr]; break; - case 'R': srcreg = bitval[bitR]; srcgather = 1; srcpos = bitpos[bitR]; break; - default: abort(); - } - switch (opcstr[pos]) { - case 'p': srcmode = Apdi; pos++; break; - case 'P': srcmode = Aipi; pos++; break; - case 'a': srcmode = Aind; pos++; break; - } - break; - case 'L': - srcmode = absl; - break; - case '#': - switch (opcstr[pos++]) { - case 'z': srcmode = imm; break; - case '0': srcmode = imm0; break; - case '1': srcmode = imm1; break; - case '2': srcmode = imm2; break; - case 'i': srcmode = immi; srcreg = (uae_s32)(uae_s8)bitval[biti]; - if (CPU_EMU_SIZE < 4) { - /* Used for branch instructions */ - srctype = 1; - srcgather = 1; - srcpos = bitpos[biti]; - } - break; - case 'j': srcmode = immi; srcreg = bitval[bitj]; - if (CPU_EMU_SIZE < 3) { - /* 1..8 for ADDQ/SUBQ and rotshi insns */ - srcgather = 1; - srctype = 3; - srcpos = bitpos[bitj]; - } - break; - case 'J': srcmode = immi; srcreg = bitval[bitJ]; - if (CPU_EMU_SIZE < 5) { - /* 0..15 */ - srcgather = 1; - srctype = 2; - srcpos = bitpos[bitJ]; - } - break; - case 'k': srcmode = immi; srcreg = bitval[bitk]; - if (CPU_EMU_SIZE < 3) { - srcgather = 1; - srctype = 4; - srcpos = bitpos[bitk]; - } - break; - case 'K': srcmode = immi; srcreg = bitval[bitK]; - if (CPU_EMU_SIZE < 5) { - /* 0..15 */ - srcgather = 1; - srctype = 5; - srcpos = bitpos[bitK]; - } - break; - case 'p': srcmode = immi; srcreg = bitval[bitK]; - if (CPU_EMU_SIZE < 5) { - /* 0..3 */ - srcgather = 1; - srctype = 7; - srcpos = bitpos[bitp]; - } - break; - default: abort(); - } - break; - case 'd': - srcreg = bitval[bitD]; - srcmode = mode_from_mr(bitval[bitd],bitval[bitD]); - if (srcmode == am_illg) - continue; - if (CPU_EMU_SIZE < 2 && - (srcmode == Areg || srcmode == Dreg || srcmode == Aind - || srcmode == Ad16 || srcmode == Ad8r || srcmode == Aipi - || srcmode == Apdi)) - { - srcgather = 1; srcpos = bitpos[bitD]; - } - if (opcstr[pos] == '[') { - pos++; - if (opcstr[pos] == '!') { - /* exclusion */ - do { - pos++; - if (mode_from_str(opcstr+pos) == srcmode) - goto nomatch; - pos += 4; - } while (opcstr[pos] == ','); - pos++; - } else { - if (opcstr[pos+4] == '-') { - /* replacement */ - if (mode_from_str(opcstr+pos) == srcmode) - srcmode = mode_from_str(opcstr+pos+5); - else - goto nomatch; - pos += 10; - } else { - /* normal */ - while(mode_from_str(opcstr+pos) != srcmode) { - pos += 4; - if (opcstr[pos] == ']') - goto nomatch; - pos++; - } - while(opcstr[pos] != ']') pos++; - pos++; - break; - } - } - } - /* Some addressing modes are invalid as destination */ - if (srcmode == imm || srcmode == PC16 || srcmode == PC8r) - goto nomatch; - break; - case 's': - srcreg = bitval[bitS]; - srcmode = mode_from_mr(bitval[bits],bitval[bitS]); - - if (srcmode == am_illg) - continue; - if (CPU_EMU_SIZE < 2 && - (srcmode == Areg || srcmode == Dreg || srcmode == Aind - || srcmode == Ad16 || srcmode == Ad8r || srcmode == Aipi - || srcmode == Apdi)) - { - srcgather = 1; srcpos = bitpos[bitS]; - } - if (opcstr[pos] == '[') { - pos++; - if (opcstr[pos] == '!') { - /* exclusion */ - do { - pos++; - if (mode_from_str(opcstr+pos) == srcmode) - goto nomatch; - pos += 4; - } while (opcstr[pos] == ','); - pos++; - } else { - if (opcstr[pos+4] == '-') { - /* replacement */ - if (mode_from_str(opcstr+pos) == srcmode) - srcmode = mode_from_str(opcstr+pos+5); - else - goto nomatch; - pos += 10; - } else { - /* normal */ - while(mode_from_str(opcstr+pos) != srcmode) { - pos += 4; - if (opcstr[pos] == ']') - goto nomatch; - pos++; - } - while(opcstr[pos] != ']') pos++; - pos++; - } - } - } - break; - default: abort(); - } - /* safety check - might have changed */ - if (srcmode != Areg && srcmode != Dreg && srcmode != Aind - && srcmode != Ad16 && srcmode != Ad8r && srcmode != Aipi - && srcmode != Apdi && srcmode != immi) - { - srcgather = 0; - } - if (srcmode == Areg && sz == sz_byte) - goto nomatch; - - if (opcstr[pos] != ',') - goto endofline; - pos++; - - /* parse the destination address */ - usedst = 1; - switch (opcstr[pos++]) { - case 'D': - destmode = Dreg; - switch (opcstr[pos++]) { - case 'r': destreg = bitval[bitr]; dstgather = 1; dstpos = bitpos[bitr]; break; - case 'R': destreg = bitval[bitR]; dstgather = 1; dstpos = bitpos[bitR]; break; - default: abort(); - } - if (dstpos < 0 || dstpos >= 32) - abort (); - break; - case 'A': - destmode = Areg; - switch (opcstr[pos++]) { - case 'r': destreg = bitval[bitr]; dstgather = 1; dstpos = bitpos[bitr]; break; - case 'R': destreg = bitval[bitR]; dstgather = 1; dstpos = bitpos[bitR]; break; - case 'x': destreg = 0; dstgather = 0; dstpos = 0; break; - default: abort(); - } - if (dstpos < 0 || dstpos >= 32) - abort (); - switch (opcstr[pos]) { - case 'p': destmode = Apdi; pos++; break; - case 'P': destmode = Aipi; pos++; break; - } - break; - case 'L': - destmode = absl; - break; - case '#': - switch (opcstr[pos++]) { - case 'z': destmode = imm; break; - case '0': destmode = imm0; break; - case '1': destmode = imm1; break; - case '2': destmode = imm2; break; - case 'i': destmode = immi; destreg = (uae_s32)(uae_s8)bitval[biti]; break; - case 'j': destmode = immi; destreg = bitval[bitj]; break; - case 'J': destmode = immi; destreg = bitval[bitJ]; break; - case 'k': destmode = immi; destreg = bitval[bitk]; break; - case 'K': destmode = immi; destreg = bitval[bitK]; break; - default: abort(); - } - break; - case 'd': - destreg = bitval[bitD]; - destmode = mode_from_mr(bitval[bitd],bitval[bitD]); - if (destmode == am_illg) - continue; - if (CPU_EMU_SIZE < 1 && - (destmode == Areg || destmode == Dreg || destmode == Aind - || destmode == Ad16 || destmode == Ad8r || destmode == Aipi - || destmode == Apdi)) - { - dstgather = 1; dstpos = bitpos[bitD]; - } - - if (opcstr[pos] == '[') { - pos++; - if (opcstr[pos] == '!') { - /* exclusion */ - do { - pos++; - if (mode_from_str(opcstr+pos) == destmode) - goto nomatch; - pos += 4; - } while (opcstr[pos] == ','); - pos++; - } else { - if (opcstr[pos+4] == '-') { - /* replacement */ - if (mode_from_str(opcstr+pos) == destmode) - destmode = mode_from_str(opcstr+pos+5); - else - goto nomatch; - pos += 10; - } else { - /* normal */ - while(mode_from_str(opcstr+pos) != destmode) { - pos += 4; - if (opcstr[pos] == ']') - goto nomatch; - pos++; - } - while(opcstr[pos] != ']') pos++; - pos++; - break; - } - } - } - /* Some addressing modes are invalid as destination */ - if (destmode == imm || destmode == PC16 || destmode == PC8r) - goto nomatch; - break; - case 's': - destreg = bitval[bitS]; - destmode = mode_from_mr(bitval[bits],bitval[bitS]); - - if (destmode == am_illg) - continue; - if (CPU_EMU_SIZE < 1 && - (destmode == Areg || destmode == Dreg || destmode == Aind - || destmode == Ad16 || destmode == Ad8r || destmode == Aipi - || destmode == Apdi)) - { - dstgather = 1; dstpos = bitpos[bitS]; - } - - if (opcstr[pos] == '[') { - pos++; - if (opcstr[pos] == '!') { - /* exclusion */ - do { - pos++; - if (mode_from_str(opcstr+pos) == destmode) - goto nomatch; - pos += 4; - } while (opcstr[pos] == ','); - pos++; - } else { - if (opcstr[pos+4] == '-') { - /* replacement */ - if (mode_from_str(opcstr+pos) == destmode) - destmode = mode_from_str(opcstr+pos+5); - else - goto nomatch; - pos += 10; - } else { - /* normal */ - while(mode_from_str(opcstr+pos) != destmode) { - pos += 4; - if (opcstr[pos] == ']') - goto nomatch; - pos++; - } - while(opcstr[pos] != ']') pos++; - pos++; - } - } - } - break; - default: abort(); - } - /* safety check - might have changed */ - if (destmode != Areg && destmode != Dreg && destmode != Aind - && destmode != Ad16 && destmode != Ad8r && destmode != Aipi - && destmode != Apdi) - { - dstgather = 0; - } - - if (destmode == Areg && sz == sz_byte) - goto nomatch; + for (i = 0; i < 5; i++) { + switch (id.flaginfo[i].flaguse) { + case fu_unused: break; + case fu_isjmp: isjmp = 1; flaglive |= 1 << i; break; + case fu_maybecc: isjmp = 1; flaglive |= 1 << i; break; + case fu_unknown: isjmp = 1; flaglive |= 1 << i; break; + case fu_used: flaglive |= 1 << i; break; + } + } + + opcstr = id.opcstr; + for (variants = 0; variants < (1 << id.n_variable); variants++) { + int bitcnt[lastbit]; + int bitval[lastbit]; + int bitpos[lastbit]; + int i; + uae_u16 opc = id.bits; + uae_u16 msk, vmsk; + int pos = 0; + int mnp = 0; + int bitno = 0; + int unsized = 1; + TCHAR mnemonic[10]; + int mnemo; + + wordsizes sz = sz_long; + int srcgather = 0, dstgather = 0; + int usesrc = 0, usedst = 0; + int srctype = 0; + int srcpos = -1, dstpos = -1; + + amodes srcmode = am_unknown, destmode = am_unknown; + int srcreg = -1, destreg = -1; + + for (i = 0; i < lastbit; i++) + bitcnt[i] = bitval[i] = 0; + + vmsk = 1 << id.n_variable; + + for (i = 0, msk = 0x8000; i < 16; i++, msk >>= 1) { + if (!(msk & id.mask)) { + int currbit = id.bitpos[bitno++]; + int bit_set; + vmsk >>= 1; + bit_set = variants & vmsk ? 1 : 0; + if (bit_set) + opc |= msk; + bitpos[currbit] = 15 - i; + bitcnt[currbit]++; + bitval[currbit] <<= 1; + bitval[currbit] |= bit_set; + } + } + + if (bitval[bitj] == 0) bitval[bitj] = 8; + /* first check whether this one does not match after all */ + if (bitval[bitz] == 3 || bitval[bitC] == 1) + continue; + if (bitcnt[bitI] && (bitval[bitI] == 0x00 || bitval[bitI] == 0xff)) + continue; + + /* bitI and bitC get copied to biti and bitc */ + if (bitcnt[bitI]) { + bitval[biti] = bitval[bitI]; bitpos[biti] = bitpos[bitI]; + } + if (bitcnt[bitC]) + bitval[bitc] = bitval[bitC]; + + pos = 0; + while (opcstr[pos] && !_istspace(opcstr[pos])) { + if (opcstr[pos] == '.') { + pos++; + unsized = 0; + switch (opcstr[pos]) { + + case 'B': sz = sz_byte; break; + case 'W': sz = sz_word; break; + case 'L': sz = sz_long; break; + case 'z': + switch (bitval[bitz]) { + case 0: sz = sz_byte; break; + case 1: sz = sz_word; break; + case 2: sz = sz_long; break; + default: abort(); + } + break; + default: abort(); + } + } else { + mnemonic[mnp] = opcstr[pos]; + if (mnemonic[mnp] == 'f') { + find = -1; + switch (bitval[bitf]) { + case 0: mnemonic[mnp] = 'R'; break; + case 1: mnemonic[mnp] = 'L'; break; + default: abort(); + } + } + mnp++; + } + pos++; + } + mnemonic[mnp] = 0; + + /* now, we have read the mnemonic and the size */ + while (opcstr[pos] && _istspace(opcstr[pos])) + pos++; + + /* A goto a day keeps the D******a away. */ + if (opcstr[pos] == 0) + goto endofline; + + /* parse the source address */ + usesrc = 1; + switch (opcstr[pos++]) { + case 'D': + srcmode = Dreg; + switch (opcstr[pos++]) { + case 'r': srcreg = bitval[bitr]; srcgather = 1; srcpos = bitpos[bitr]; break; + case 'R': srcreg = bitval[bitR]; srcgather = 1; srcpos = bitpos[bitR]; break; + default: abort(); + } + break; + case 'A': + srcmode = Areg; + switch (opcstr[pos++]) { + case 'r': srcreg = bitval[bitr]; srcgather = 1; srcpos = bitpos[bitr]; break; + case 'R': srcreg = bitval[bitR]; srcgather = 1; srcpos = bitpos[bitR]; break; + default: abort(); + } + switch (opcstr[pos]) { + case 'p': srcmode = Apdi; pos++; break; + case 'P': srcmode = Aipi; pos++; break; + case 'a': srcmode = Aind; pos++; break; + } + break; + case 'L': + srcmode = absl; + break; + case '#': + switch (opcstr[pos++]) { + case 'z': srcmode = imm; break; + case '0': srcmode = imm0; break; + case '1': srcmode = imm1; break; + case '2': srcmode = imm2; break; + case 'i': srcmode = immi; srcreg = (uae_s32)(uae_s8)bitval[biti]; + if (CPU_EMU_SIZE < 4) { + /* Used for branch instructions */ + srctype = 1; + srcgather = 1; + srcpos = bitpos[biti]; + } + break; + case 'j': srcmode = immi; srcreg = bitval[bitj]; + if (CPU_EMU_SIZE < 3) { + /* 1..8 for ADDQ/SUBQ and rotshi insns */ + srcgather = 1; + srctype = 3; + srcpos = bitpos[bitj]; + } + break; + case 'J': srcmode = immi; srcreg = bitval[bitJ]; + if (CPU_EMU_SIZE < 5) { + /* 0..15 */ + srcgather = 1; + srctype = 2; + srcpos = bitpos[bitJ]; + } + break; + case 'k': srcmode = immi; srcreg = bitval[bitk]; + if (CPU_EMU_SIZE < 3) { + srcgather = 1; + srctype = 4; + srcpos = bitpos[bitk]; + } + break; + case 'K': srcmode = immi; srcreg = bitval[bitK]; + if (CPU_EMU_SIZE < 5) { + /* 0..15 */ + srcgather = 1; + srctype = 5; + srcpos = bitpos[bitK]; + } + break; + case 'p': srcmode = immi; srcreg = bitval[bitK]; + if (CPU_EMU_SIZE < 5) { + /* 0..3 */ + srcgather = 1; + srctype = 7; + srcpos = bitpos[bitp]; + } + break; + default: abort(); + } + break; + case 'd': + srcreg = bitval[bitD]; + srcmode = mode_from_mr(bitval[bitd],bitval[bitD]); + if (srcmode == am_illg) + continue; + if (CPU_EMU_SIZE < 2 && + (srcmode == Areg || srcmode == Dreg || srcmode == Aind + || srcmode == Ad16 || srcmode == Ad8r || srcmode == Aipi + || srcmode == Apdi)) + { + srcgather = 1; srcpos = bitpos[bitD]; + } + if (opcstr[pos] == '[') { + pos++; + if (opcstr[pos] == '!') { + /* exclusion */ + do { + pos++; + if (mode_from_str(opcstr+pos) == srcmode) + goto nomatch; + pos += 4; + } while (opcstr[pos] == ','); + pos++; + } else { + if (opcstr[pos+4] == '-') { + /* replacement */ + if (mode_from_str(opcstr+pos) == srcmode) + srcmode = mode_from_str(opcstr+pos+5); + else + goto nomatch; + pos += 10; + } else { + /* normal */ + while(mode_from_str(opcstr+pos) != srcmode) { + pos += 4; + if (opcstr[pos] == ']') + goto nomatch; + pos++; + } + while(opcstr[pos] != ']') pos++; + pos++; + break; + } + } + } + /* Some addressing modes are invalid as destination */ + if (srcmode == imm || srcmode == PC16 || srcmode == PC8r) + goto nomatch; + break; + case 's': + srcreg = bitval[bitS]; + srcmode = mode_from_mr(bitval[bits],bitval[bitS]); + + if (srcmode == am_illg) + continue; + if (CPU_EMU_SIZE < 2 && + (srcmode == Areg || srcmode == Dreg || srcmode == Aind + || srcmode == Ad16 || srcmode == Ad8r || srcmode == Aipi + || srcmode == Apdi)) + { + srcgather = 1; srcpos = bitpos[bitS]; + } + if (opcstr[pos] == '[') { + pos++; + if (opcstr[pos] == '!') { + /* exclusion */ + do { + pos++; + if (mode_from_str(opcstr+pos) == srcmode) + goto nomatch; + pos += 4; + } while (opcstr[pos] == ','); + pos++; + } else { + if (opcstr[pos+4] == '-') { + /* replacement */ + if (mode_from_str(opcstr+pos) == srcmode) + srcmode = mode_from_str(opcstr+pos+5); + else + goto nomatch; + pos += 10; + } else { + /* normal */ + while(mode_from_str(opcstr+pos) != srcmode) { + pos += 4; + if (opcstr[pos] == ']') + goto nomatch; + pos++; + } + while(opcstr[pos] != ']') pos++; + pos++; + } + } + } + break; + default: abort(); + } + /* safety check - might have changed */ + if (srcmode != Areg && srcmode != Dreg && srcmode != Aind + && srcmode != Ad16 && srcmode != Ad8r && srcmode != Aipi + && srcmode != Apdi && srcmode != immi) + { + srcgather = 0; + } + if (srcmode == Areg && sz == sz_byte) + goto nomatch; + + if (opcstr[pos] != ',') + goto endofline; + pos++; + + /* parse the destination address */ + usedst = 1; + switch (opcstr[pos++]) { + case 'D': + destmode = Dreg; + switch (opcstr[pos++]) { + case 'r': destreg = bitval[bitr]; dstgather = 1; dstpos = bitpos[bitr]; break; + case 'R': destreg = bitval[bitR]; dstgather = 1; dstpos = bitpos[bitR]; break; + default: abort(); + } + if (dstpos < 0 || dstpos >= 32) + abort (); + break; + case 'A': + destmode = Areg; + switch (opcstr[pos++]) { + case 'r': destreg = bitval[bitr]; dstgather = 1; dstpos = bitpos[bitr]; break; + case 'R': destreg = bitval[bitR]; dstgather = 1; dstpos = bitpos[bitR]; break; + case 'x': destreg = 0; dstgather = 0; dstpos = 0; break; + default: abort(); + } + if (dstpos < 0 || dstpos >= 32) + abort (); + switch (opcstr[pos]) { + case 'p': destmode = Apdi; pos++; break; + case 'P': destmode = Aipi; pos++; break; + } + break; + case 'L': + destmode = absl; + break; + case '#': + switch (opcstr[pos++]) { + case 'z': destmode = imm; break; + case '0': destmode = imm0; break; + case '1': destmode = imm1; break; + case '2': destmode = imm2; break; + case 'i': destmode = immi; destreg = (uae_s32)(uae_s8)bitval[biti]; break; + case 'j': destmode = immi; destreg = bitval[bitj]; break; + case 'J': destmode = immi; destreg = bitval[bitJ]; break; + case 'k': destmode = immi; destreg = bitval[bitk]; break; + case 'K': destmode = immi; destreg = bitval[bitK]; break; + default: abort(); + } + break; + case 'd': + destreg = bitval[bitD]; + destmode = mode_from_mr(bitval[bitd],bitval[bitD]); + if (destmode == am_illg) + continue; + if (CPU_EMU_SIZE < 1 && + (destmode == Areg || destmode == Dreg || destmode == Aind + || destmode == Ad16 || destmode == Ad8r || destmode == Aipi + || destmode == Apdi)) + { + dstgather = 1; dstpos = bitpos[bitD]; + } + + if (opcstr[pos] == '[') { + pos++; + if (opcstr[pos] == '!') { + /* exclusion */ + do { + pos++; + if (mode_from_str(opcstr+pos) == destmode) + goto nomatch; + pos += 4; + } while (opcstr[pos] == ','); + pos++; + } else { + if (opcstr[pos+4] == '-') { + /* replacement */ + if (mode_from_str(opcstr+pos) == destmode) + destmode = mode_from_str(opcstr+pos+5); + else + goto nomatch; + pos += 10; + } else { + /* normal */ + while(mode_from_str(opcstr+pos) != destmode) { + pos += 4; + if (opcstr[pos] == ']') + goto nomatch; + pos++; + } + while(opcstr[pos] != ']') pos++; + pos++; + break; + } + } + } + /* Some addressing modes are invalid as destination */ + if (destmode == imm || destmode == PC16 || destmode == PC8r) + goto nomatch; + break; + case 's': + destreg = bitval[bitS]; + destmode = mode_from_mr(bitval[bits],bitval[bitS]); + + if (destmode == am_illg) + continue; + if (CPU_EMU_SIZE < 1 && + (destmode == Areg || destmode == Dreg || destmode == Aind + || destmode == Ad16 || destmode == Ad8r || destmode == Aipi + || destmode == Apdi)) + { + dstgather = 1; dstpos = bitpos[bitS]; + } + + if (opcstr[pos] == '[') { + pos++; + if (opcstr[pos] == '!') { + /* exclusion */ + do { + pos++; + if (mode_from_str(opcstr+pos) == destmode) + goto nomatch; + pos += 4; + } while (opcstr[pos] == ','); + pos++; + } else { + if (opcstr[pos+4] == '-') { + /* replacement */ + if (mode_from_str(opcstr+pos) == destmode) + destmode = mode_from_str(opcstr+pos+5); + else + goto nomatch; + pos += 10; + } else { + /* normal */ + while(mode_from_str(opcstr+pos) != destmode) { + pos += 4; + if (opcstr[pos] == ']') + goto nomatch; + pos++; + } + while(opcstr[pos] != ']') pos++; + pos++; + } + } + } + break; + default: abort(); + } + /* safety check - might have changed */ + if (destmode != Areg && destmode != Dreg && destmode != Aind + && destmode != Ad16 && destmode != Ad8r && destmode != Aipi + && destmode != Apdi) + { + dstgather = 0; + } + + if (destmode == Areg && sz == sz_byte) + goto nomatch; #if 0 - if (sz == sz_byte && (destmode == Aipi || destmode == Apdi)) { - dstgather = 0; - } + if (sz == sz_byte && (destmode == Aipi || destmode == Apdi)) { + dstgather = 0; + } #endif -endofline: - /* now, we have a match */ - if (table68k[opc].mnemo != i_ILLG) - ;//write_log (L"Double match: %x: %s\n", opc, opcstr); - if (find == -1) { - for (find = 0;; find++) { - if (_tcscmp (mnemonic, lookuptab[find].name) == 0) { - table68k[opc].mnemo = lookuptab[find].mnemo; - break; - } - if (_tcslen (lookuptab[find].name) == 0) - abort(); - } - } - else { - table68k[opc].mnemo = lookuptab[find].mnemo; - } - table68k[opc].cc = bitval[bitc]; - if (table68k[opc].mnemo == i_BTST - || table68k[opc].mnemo == i_BSET - || table68k[opc].mnemo == i_BCLR - || table68k[opc].mnemo == i_BCHG) - { - sz = destmode == Dreg ? sz_long : sz_byte; - } - table68k[opc].size = sz; - table68k[opc].sreg = srcreg; - table68k[opc].dreg = destreg; - table68k[opc].smode = srcmode; - table68k[opc].dmode = destmode; - table68k[opc].spos = srcgather ? srcpos : -1; - table68k[opc].dpos = dstgather ? dstpos : -1; - table68k[opc].suse = usesrc; - table68k[opc].duse = usedst; - table68k[opc].stype = srctype; - table68k[opc].plev = id.plevel; - table68k[opc].clev = specialcase(opc, id.cpulevel); - + endofline: + /* now, we have a match */ + if (table68k[opc].mnemo != i_ILLG) + ;//write_log (_T("Double match: %x: %s\n"), opc, opcstr); + if (find == -1) { + for (find = 0;; find++) { + if (_tcscmp (mnemonic, lookuptab[find].name) == 0) { + table68k[opc].mnemo = lookuptab[find].mnemo; + break; + } + if (_tcslen (lookuptab[find].name) == 0) + abort(); + } + } + else { + table68k[opc].mnemo = lookuptab[find].mnemo; + } + table68k[opc].cc = bitval[bitc]; + mnemo = table68k[opc].mnemo; + if (mnemo == i_BTST + || mnemo == i_BSET + || mnemo == i_BCLR + || mnemo == i_BCHG) + { + sz = destmode == Dreg ? sz_long : sz_byte; + unsized = 0; + } + if (mnemo == i_JSR || mnemo == i_JMP) { + unsized = 1; + } + + table68k[opc].size = sz; + table68k[opc].unsized = unsized; + table68k[opc].sduse = id.sduse; + table68k[opc].sreg = srcreg; + table68k[opc].dreg = destreg; + table68k[opc].smode = srcmode; + table68k[opc].dmode = destmode; + table68k[opc].spos = srcgather ? srcpos : -1; + table68k[opc].dpos = dstgather ? dstpos : -1; + table68k[opc].suse = usesrc; + table68k[opc].duse = usedst; + table68k[opc].stype = srctype; + table68k[opc].plev = id.plevel; + table68k[opc].clev = id.cpulevel; + table68k[opc].unimpclev = id.unimpcpulevel; + table68k[opc].head = id.head; + table68k[opc].tail = id.tail; + table68k[opc].clocks = id.clocks; + table68k[opc].fetchmode = id.fetchmode; + #if 0 - for (i = 0; i < 5; i++) { - table68k[opc].flaginfo[i].flagset = id.flaginfo[i].flagset; - table68k[opc].flaginfo[i].flaguse = id.flaginfo[i].flaguse; - } + for (i = 0; i < 5; i++) { + table68k[opc].flaginfo[i].flagset = id.flaginfo[i].flagset; + table68k[opc].flaginfo[i].flaguse = id.flaginfo[i].flaguse; + } #endif - table68k[opc].flagdead = flagdead; - table68k[opc].flaglive = flaglive; - table68k[opc].isjmp = isjmp; -nomatch: - /* FOO! */; - } + table68k[opc].flagdead = flagdead; + table68k[opc].flaglive = flaglive; + table68k[opc].isjmp = isjmp; + nomatch: + /* FOO! */; + } } void read_table68k (void) { - int i; - - free (table68k); - table68k = xmalloc (struct instr, 65536); - for (i = 0; i < 65536; i++) { - table68k[i].mnemo = i_ILLG; - table68k[i].handler = -1; - } - for (i = 0; i < n_defs68k; i++) { - build_insn (i); - } + int i; + + free (table68k); + table68k = xmalloc (struct instr, 65536); + for (i = 0; i < 65536; i++) { + table68k[i].mnemo = i_ILLG; + table68k[i].handler = -1; + } + for (i = 0; i < n_defs68k; i++) { + build_insn (i); + } } static int imismatch; static void handle_merges (long int opcode) { - uae_u16 smsk; - uae_u16 dmsk; - int sbitdst, dstend; - int srcreg, dstreg; - - if (table68k[opcode].spos == -1) { - sbitdst = 1; smsk = 0; - } else { - switch (table68k[opcode].stype) { - case 0: - smsk = 7; sbitdst = 8; break; - case 1: - smsk = 255; sbitdst = 256; break; - case 2: - smsk = 15; sbitdst = 16; break; - case 3: - smsk = 7; sbitdst = 8; break; - case 4: - smsk = 7; sbitdst = 8; break; - case 5: - smsk = 63; sbitdst = 64; break; - case 7: - smsk = 3; sbitdst = 4; break; - default: - smsk = 0; sbitdst = 0; - abort(); - break; - } - smsk <<= table68k[opcode].spos; - } - if (table68k[opcode].dpos == -1) { - dstend = 1; dmsk = 0; - } else { - dmsk = 7 << table68k[opcode].dpos; - dstend = 8; - } - for (srcreg=0; srcreg < sbitdst; srcreg++) { - for (dstreg=0; dstreg < dstend; dstreg++) { - uae_u16 code = (uae_u16)opcode; - - code = (code & ~smsk) | (srcreg << table68k[opcode].spos); - code = (code & ~dmsk) | (dstreg << table68k[opcode].dpos); - - /* Check whether this is in fact the same instruction. - * The instructions should never differ, except for the - * Bcc.(BW) case. */ - if (table68k[code].mnemo != table68k[opcode].mnemo - || table68k[code].size != table68k[opcode].size - || table68k[code].suse != table68k[opcode].suse - || table68k[code].duse != table68k[opcode].duse) - { - imismatch++; continue; - } - if (table68k[opcode].suse - && (table68k[opcode].spos != table68k[code].spos - || table68k[opcode].smode != table68k[code].smode - || table68k[opcode].stype != table68k[code].stype)) - { - imismatch++; continue; - } - if (table68k[opcode].duse - && (table68k[opcode].dpos != table68k[code].dpos - || table68k[opcode].dmode != table68k[code].dmode)) - { - imismatch++; continue; - } - - if (code != opcode) - table68k[code].handler = opcode; - } - } + uae_u16 smsk; + uae_u16 dmsk; + int sbitdst, dstend; + int srcreg, dstreg; + + if (table68k[opcode].spos == -1) { + sbitdst = 1; smsk = 0; + } else { + switch (table68k[opcode].stype) { + case 0: + smsk = 7; sbitdst = 8; break; + case 1: + smsk = 255; sbitdst = 256; break; + case 2: + smsk = 15; sbitdst = 16; break; + case 3: + smsk = 7; sbitdst = 8; break; + case 4: + smsk = 7; sbitdst = 8; break; + case 5: + smsk = 63; sbitdst = 64; break; + case 7: + smsk = 3; sbitdst = 4; break; + default: + smsk = 0; sbitdst = 0; + abort(); + break; + } + smsk <<= table68k[opcode].spos; + } + if (table68k[opcode].dpos == -1) { + dstend = 1; dmsk = 0; + } else { + dmsk = 7 << table68k[opcode].dpos; + dstend = 8; + } + for (srcreg=0; srcreg < sbitdst; srcreg++) { + for (dstreg=0; dstreg < dstend; dstreg++) { + uae_u16 code = (uae_u16)opcode; + + code = (code & ~smsk) | (srcreg << table68k[opcode].spos); + code = (code & ~dmsk) | (dstreg << table68k[opcode].dpos); + + /* Check whether this is in fact the same instruction. + * The instructions should never differ, except for the + * Bcc.(BW) case. */ + if (table68k[code].mnemo != table68k[opcode].mnemo + || table68k[code].size != table68k[opcode].size + || table68k[code].suse != table68k[opcode].suse + || table68k[code].duse != table68k[opcode].duse) + { + imismatch++; continue; + } + if (table68k[opcode].suse + && (table68k[opcode].spos != table68k[code].spos + || table68k[opcode].smode != table68k[code].smode + || table68k[opcode].stype != table68k[code].stype)) + { + imismatch++; continue; + } + if (table68k[opcode].duse + && (table68k[opcode].dpos != table68k[code].dpos + || table68k[opcode].dmode != table68k[code].dmode)) + { + imismatch++; continue; + } + + if (code != opcode) + table68k[code].handler = opcode; + } + } } void do_merges (void) { - long int opcode; - int nr = 0; - imismatch = 0; - for (opcode = 0; opcode < 65536; opcode++) { - if (table68k[opcode].handler != -1 || table68k[opcode].mnemo == i_ILLG) - continue; - nr++; - handle_merges (opcode); - } - nr_cpuop_funcs = nr; + long int opcode; + int nr = 0; + imismatch = 0; + for (opcode = 0; opcode < 65536; opcode++) { + if (table68k[opcode].handler != -1 || table68k[opcode].mnemo == i_ILLG) + continue; + nr++; + handle_merges (opcode); + } + nr_cpuop_funcs = nr; } int get_no_mismatches (void) { - return imismatch; + return imismatch; }