|
|
1.1 ! root 1: /* ! 2: * UAE - The Un*x Amiga Emulator ! 3: * ! 4: * Read 68000 CPU specs from file "table68k" ! 5: * ! 6: * Copyright 1995,1996 Bernd Schmidt ! 7: */ ! 8: ! 9: #include "sysconfig.h" ! 10: #include "sysdeps.h" ! 11: #include <ctype.h> ! 12: #include <string.h> ! 13: ! 14: #include "readcpu.h" ! 15: ! 16: int nr_cpuop_funcs; ! 17: ! 18: struct mnemolookup lookuptab[] = { ! 19: { i_ILLG, _T("ILLEGAL"), NULL, 0 }, ! 20: { i_OR, _T("OR"), NULL, 1 }, ! 21: { i_CHK, _T("CHK"), NULL, 0 }, ! 22: { i_CHK2, _T("CHK2"), NULL, 0 }, ! 23: { i_AND, _T("AND"), NULL, 1 }, ! 24: { i_EOR, _T("EOR"), NULL, 1 }, ! 25: { i_ORSR, _T("ORSR"), NULL, 0 }, ! 26: { i_ANDSR, _T("ANDSR"), NULL, 0 }, ! 27: { i_EORSR, _T("EORSR"), NULL, 0 }, ! 28: { i_SUB, _T("SUB"), NULL, 1 }, ! 29: { i_SUBA, _T("SUBA"), NULL, 1 }, ! 30: { i_SUBX, _T("SUBX"), NULL, 0 }, ! 31: { i_SBCD, _T("SBCD"), NULL, 0 }, ! 32: { i_ADD, _T("ADD"), NULL, 1 }, ! 33: { i_ADDA, _T("ADDA"), NULL, 1 }, ! 34: { i_ADDX, _T("ADDX"), NULL, 0 }, ! 35: { i_ABCD, _T("ABCD"), NULL, 0 }, ! 36: { i_NEG, _T("NEG"), NULL, 1 }, ! 37: { i_NEGX, _T("NEGX"), NULL, 1 }, ! 38: { i_NBCD, _T("NBCD"), NULL, 0 }, ! 39: { i_CLR, _T("CLR"), NULL, 0 }, ! 40: { i_NOT, _T("NOT"), NULL, 1 }, ! 41: { i_TST, _T("TST"), NULL, 1 }, ! 42: { i_BTST, _T("BTST"), NULL, 1 }, ! 43: { i_BCHG, _T("BCHG"), NULL, 1 }, ! 44: { i_BCLR, _T("BCLR"), NULL, 1 }, ! 45: { i_BSET, _T("BSET"), NULL, 1 }, ! 46: { i_CMP, _T("CMP"), NULL, 1 }, ! 47: { i_CMPM, _T("CMPM"), NULL, 1 }, ! 48: { i_CMPA, _T("CMPA"), NULL, 1 }, ! 49: { i_MVPRM, _T("MVPRM"), NULL, 0 }, ! 50: { i_MVPMR, _T("MVPMR"), NULL, 0 }, ! 51: { i_MOVE, _T("MOVE"), NULL, 1 }, ! 52: { i_MOVEA, _T("MOVEA"), NULL, 1 }, ! 53: { i_MVSR2, _T("MVSR2"), NULL, 0 }, ! 54: { i_MV2SR, _T("MV2SR"), NULL, 0 }, ! 55: { i_SWAP, _T("SWAP"), NULL, 0 }, ! 56: { i_EXG, _T("EXG"), NULL, 0 }, ! 57: { i_EXT, _T("EXT"), NULL, 0 }, ! 58: { i_MVMEL, _T("MVMEL"), _T("MOVEM"), 0 }, ! 59: { i_MVMLE, _T("MVMLE"), _T("MOVEM"), 0 }, ! 60: { i_TRAP, _T("TRAP"), NULL, 0 }, ! 61: { i_MVR2USP, _T("MVR2USP"), NULL, 0 }, ! 62: { i_MVUSP2R, _T("MVUSP2R"), NULL, 0 }, ! 63: { i_NOP, _T("NOP"), NULL, 0 }, ! 64: { i_RESET, _T("RESET"), NULL, 0 }, ! 65: { i_RTE, _T("RTE"), NULL, 0 }, ! 66: { i_RTD, _T("RTD"), NULL, 0 }, ! 67: { i_LINK, _T("LINK"), NULL, 0 }, ! 68: { i_UNLK, _T("UNLK"), NULL, 0 }, ! 69: { i_RTS, _T("RTS"), NULL, 0 }, ! 70: { i_STOP, _T("STOP"), NULL, 0 }, ! 71: { i_TRAPV, _T("TRAPV"), NULL, 0 }, ! 72: { i_RTR, _T("RTR"), NULL, 0 }, ! 73: { i_JSR, _T("JSR"), NULL, 0 }, ! 74: { i_JMP, _T("JMP"), NULL, 0 }, ! 75: { i_BSR, _T("BSR"), NULL, 0 }, ! 76: { i_Bcc, _T("Bcc"), NULL, 0 }, ! 77: { i_LEA, _T("LEA"), NULL, 0 }, ! 78: { i_PEA, _T("PEA"), NULL, 0 }, ! 79: { i_DBcc, _T("DBcc"), NULL, 0 }, ! 80: { i_Scc, _T("Scc"), NULL, 1 }, ! 81: { i_DIVU, _T("DIVU"), NULL, 1 }, ! 82: { i_DIVS, _T("DIVS"), NULL, 1 }, ! 83: { i_MULU, _T("MULU"), NULL, 1 }, ! 84: { i_MULS, _T("MULS"), NULL, 1 }, ! 85: { i_ASR, _T("ASR"), NULL, }, ! 86: { i_ASL, _T("ASL"), NULL, 0 }, ! 87: { i_LSR, _T("LSR"), NULL, 0 }, ! 88: { i_LSL, _T("LSL"), NULL, 0 }, ! 89: { i_ROL, _T("ROL"), NULL, 0 }, ! 90: { i_ROR, _T("ROR"), NULL, 0 }, ! 91: { i_ROXL, _T("ROXL"), NULL, 1 }, ! 92: { i_ROXR, _T("ROXR"), NULL, 1 }, ! 93: { i_ASRW, _T("ASRW"), NULL, 1 }, ! 94: { i_ASLW, _T("ASLW"), NULL, 1 }, ! 95: { i_LSRW, _T("LSRW"), NULL, 1 }, ! 96: { i_LSLW, _T("LSLW"), NULL, 1 }, ! 97: { i_ROLW, _T("ROLW"), NULL, 1 }, ! 98: { i_RORW, _T("RORW"), NULL, 1 }, ! 99: { i_ROXLW, _T("ROXLW"), NULL, 1 }, ! 100: { i_ROXRW, _T("ROXRW"), NULL, 1 }, ! 101: ! 102: { i_MOVE2C, _T("MOVE2C"), _T("MOVEC"), 0 }, ! 103: { i_MOVEC2, _T("MOVEC2"), _T("MOVEC"), 0 }, ! 104: { i_CAS, _T("CAS"), NULL, 1 }, ! 105: { i_CAS2, _T("CAS2"), NULL, 1 }, ! 106: { i_MULL, _T("MULL"), NULL, 0 }, ! 107: { i_DIVL, _T("DIVL"), NULL, 0 }, ! 108: { i_BFTST, _T("BFTST"), NULL, 0 }, ! 109: { i_BFEXTU, _T("BFEXTU"), NULL, 0 }, ! 110: { i_BFCHG, _T("BFCHG"), NULL, 0 }, ! 111: { i_BFEXTS, _T("BFEXTS"), NULL, 0 }, ! 112: { i_BFCLR, _T("BFCLR"), NULL, 0 }, ! 113: { i_BFFFO, _T("BFFFO"), NULL, 0 }, ! 114: { i_BFSET, _T("BFSET"), NULL, 0 }, ! 115: { i_BFINS, _T("BFINS"), NULL, 0 }, ! 116: { i_PACK, _T("PACK"), NULL, 0 }, ! 117: { i_UNPK, _T("UNPK"), NULL, 0 }, ! 118: { i_TAS, _T("TAS"), NULL, 1 }, ! 119: { i_BKPT, _T("BKPT"), NULL, 0 }, ! 120: { i_CALLM, _T("CALLM"), NULL, 0 }, ! 121: { i_RTM, _T("RTM"), NULL, 0 }, ! 122: { i_TRAPcc, _T("TRAPcc"), NULL, 0 }, ! 123: { i_MOVES, _T("MOVES"), NULL, 1 }, ! 124: { i_FPP, _T("FPP"), NULL, 0 }, ! 125: { i_FDBcc, _T("FDBcc"), NULL, 0 }, ! 126: { i_FScc, _T("FScc"), NULL, 0 }, ! 127: { i_FTRAPcc, _T("FTRAPcc"), NULL, 0 }, ! 128: { i_FBcc, _T("FBcc"), NULL, 0 }, ! 129: { i_FBcc, _T("FBcc"), NULL, 0 }, ! 130: { i_FSAVE, _T("FSAVE"), NULL, 0 }, ! 131: { i_FRESTORE, _T("FRESTORE"), NULL, 0 }, ! 132: ! 133: { i_CINVL, _T("CINVL"), NULL, 0 }, ! 134: { i_CINVP, _T("CINVP"), NULL, 0 }, ! 135: { i_CINVA, _T("CINVA"), NULL, 0 }, ! 136: { i_CPUSHL, _T("CPUSHL"), NULL, 0 }, ! 137: { i_CPUSHP, _T("CPUSHP"), NULL, 0 }, ! 138: { i_CPUSHA, _T("CPUSHA"), NULL, 0 }, ! 139: { i_MOVE16, _T("MOVE16"), NULL, 0 }, ! 140: ! 141: { i_MMUOP030, _T("MMUOP030"), NULL, 0 }, ! 142: { i_PFLUSHN, _T("PFLUSHN"), NULL, 0 }, ! 143: { i_PFLUSH, _T("PFLUSH"), NULL, 0 }, ! 144: { i_PFLUSHAN, _T("PFLUSHAN"), NULL, 0 }, ! 145: { i_PFLUSHA, _T("PFLUSHA"), NULL, 0 }, ! 146: ! 147: { i_PLPAR, _T("PLPAR"), NULL, 0 }, ! 148: { i_PLPAW, _T("PLPAW"), NULL, 0 }, ! 149: { i_PTESTR, _T("PTESTR"), NULL, 0 }, ! 150: { i_PTESTW, _T("PTESTW"), NULL, 0 }, ! 151: ! 152: { i_LPSTOP, _T("LPSTOP"), NULL, 0 }, ! 153: { i_ILLG, _T(""), NULL, 0 }, ! 154: }; ! 155: ! 156: struct instr *table68k; ! 157: ! 158: static amodes mode_from_str (const TCHAR *str) ! 159: { ! 160: if (_tcsncmp (str, _T("Dreg"), 4) == 0) return Dreg; ! 161: if (_tcsncmp (str, _T("Areg"), 4) == 0) return Areg; ! 162: if (_tcsncmp (str, _T("Aind"), 4) == 0) return Aind; ! 163: if (_tcsncmp (str, _T("Apdi"), 4) == 0) return Apdi; ! 164: if (_tcsncmp (str, _T("Aipi"), 4) == 0) return Aipi; ! 165: if (_tcsncmp (str, _T("Ad16"), 4) == 0) return Ad16; ! 166: if (_tcsncmp (str, _T("Ad8r"), 4) == 0) return Ad8r; ! 167: if (_tcsncmp (str, _T("absw"), 4) == 0) return absw; ! 168: if (_tcsncmp (str, _T("absl"), 4) == 0) return absl; ! 169: if (_tcsncmp (str, _T("PC16"), 4) == 0) return PC16; ! 170: if (_tcsncmp (str, _T("PC8r"), 4) == 0) return PC8r; ! 171: if (_tcsncmp (str, _T("Immd"), 4) == 0) return imm; ! 172: abort (); ! 173: return 0; ! 174: } ! 175: ! 176: STATIC_INLINE amodes mode_from_mr (int mode, int reg) ! 177: { ! 178: switch (mode) { ! 179: case 0: return Dreg; ! 180: case 1: return Areg; ! 181: case 2: return Aind; ! 182: case 3: return Aipi; ! 183: case 4: return Apdi; ! 184: case 5: return Ad16; ! 185: case 6: return Ad8r; ! 186: case 7: ! 187: switch (reg) { ! 188: case 0: return absw; ! 189: case 1: return absl; ! 190: case 2: return PC16; ! 191: case 3: return PC8r; ! 192: case 4: return imm; ! 193: case 5: ! 194: case 6: ! 195: case 7: return am_illg; ! 196: } ! 197: } ! 198: abort (); ! 199: return 0; ! 200: } ! 201: ! 202: static void build_insn (int insn) ! 203: { ! 204: int find = -1; ! 205: int variants; ! 206: int isjmp = 0; ! 207: struct instr_def id; ! 208: const TCHAR *opcstr; ! 209: int i; ! 210: ! 211: int flaglive = 0, flagdead = 0; ! 212: ! 213: id = defs68k[insn]; ! 214: ! 215: /* Note: We treat anything with unknown flags as a jump. That ! 216: is overkill, but "the programmer" was lazy quite often, and ! 217: *this* programmer can't be bothered to work out what can and ! 218: can't trap. Usually, this will be overwritten with the gencomp ! 219: based information, anyway. */ ! 220: ! 221: for (i = 0; i < 5; i++) { ! 222: switch (id.flaginfo[i].flagset){ ! 223: case fa_unset: break; ! 224: case fa_isjmp: isjmp = 1; break; ! 225: case fa_isbranch: isjmp = 1; break; ! 226: case fa_zero: flagdead |= 1 << i; break; ! 227: case fa_one: flagdead |= 1 << i; break; ! 228: case fa_dontcare: flagdead |= 1 << i; break; ! 229: case fa_unknown: isjmp = 1; flagdead = -1; goto out1; ! 230: case fa_set: flagdead |= 1 << i; break; ! 231: } ! 232: } ! 233: ! 234: out1: ! 235: for (i = 0; i < 5; i++) { ! 236: switch (id.flaginfo[i].flaguse) { ! 237: case fu_unused: break; ! 238: case fu_isjmp: isjmp = 1; flaglive |= 1 << i; break; ! 239: case fu_maybecc: isjmp = 1; flaglive |= 1 << i; break; ! 240: case fu_unknown: isjmp = 1; flaglive |= 1 << i; break; ! 241: case fu_used: flaglive |= 1 << i; break; ! 242: } ! 243: } ! 244: ! 245: opcstr = id.opcstr; ! 246: for (variants = 0; variants < (1 << id.n_variable); variants++) { ! 247: int bitcnt[lastbit]; ! 248: int bitval[lastbit]; ! 249: int bitpos[lastbit]; ! 250: int i; ! 251: uae_u16 opc = id.bits; ! 252: uae_u16 msk, vmsk; ! 253: int pos = 0; ! 254: int mnp = 0; ! 255: int bitno = 0; ! 256: int unsized = 1; ! 257: TCHAR mnemonic[10]; ! 258: int mnemo; ! 259: ! 260: wordsizes sz = sz_long; ! 261: int srcgather = 0, dstgather = 0; ! 262: int usesrc = 0, usedst = 0; ! 263: int srctype = 0; ! 264: int srcpos = -1, dstpos = -1; ! 265: ! 266: amodes srcmode = am_unknown, destmode = am_unknown; ! 267: int srcreg = -1, destreg = -1; ! 268: ! 269: for (i = 0; i < lastbit; i++) ! 270: bitcnt[i] = bitval[i] = 0; ! 271: ! 272: vmsk = 1 << id.n_variable; ! 273: ! 274: for (i = 0, msk = 0x8000; i < 16; i++, msk >>= 1) { ! 275: if (!(msk & id.mask)) { ! 276: int currbit = id.bitpos[bitno++]; ! 277: int bit_set; ! 278: vmsk >>= 1; ! 279: bit_set = variants & vmsk ? 1 : 0; ! 280: if (bit_set) ! 281: opc |= msk; ! 282: bitpos[currbit] = 15 - i; ! 283: bitcnt[currbit]++; ! 284: bitval[currbit] <<= 1; ! 285: bitval[currbit] |= bit_set; ! 286: } ! 287: } ! 288: ! 289: if (bitval[bitj] == 0) bitval[bitj] = 8; ! 290: /* first check whether this one does not match after all */ ! 291: if (bitval[bitz] == 3 || bitval[bitC] == 1) ! 292: continue; ! 293: if (bitcnt[bitI] && (bitval[bitI] == 0x00 || bitval[bitI] == 0xff)) ! 294: continue; ! 295: ! 296: /* bitI and bitC get copied to biti and bitc */ ! 297: if (bitcnt[bitI]) { ! 298: bitval[biti] = bitval[bitI]; bitpos[biti] = bitpos[bitI]; ! 299: } ! 300: if (bitcnt[bitC]) ! 301: bitval[bitc] = bitval[bitC]; ! 302: ! 303: pos = 0; ! 304: while (opcstr[pos] && !_istspace(opcstr[pos])) { ! 305: if (opcstr[pos] == '.') { ! 306: pos++; ! 307: unsized = 0; ! 308: switch (opcstr[pos]) { ! 309: ! 310: case 'B': sz = sz_byte; break; ! 311: case 'W': sz = sz_word; break; ! 312: case 'L': sz = sz_long; break; ! 313: case 'z': ! 314: switch (bitval[bitz]) { ! 315: case 0: sz = sz_byte; break; ! 316: case 1: sz = sz_word; break; ! 317: case 2: sz = sz_long; break; ! 318: default: abort(); ! 319: } ! 320: break; ! 321: default: abort(); ! 322: } ! 323: } else { ! 324: mnemonic[mnp] = opcstr[pos]; ! 325: if (mnemonic[mnp] == 'f') { ! 326: find = -1; ! 327: switch (bitval[bitf]) { ! 328: case 0: mnemonic[mnp] = 'R'; break; ! 329: case 1: mnemonic[mnp] = 'L'; break; ! 330: default: abort(); ! 331: } ! 332: } ! 333: mnp++; ! 334: } ! 335: pos++; ! 336: } ! 337: mnemonic[mnp] = 0; ! 338: ! 339: /* now, we have read the mnemonic and the size */ ! 340: while (opcstr[pos] && _istspace(opcstr[pos])) ! 341: pos++; ! 342: ! 343: /* A goto a day keeps the D******a away. */ ! 344: if (opcstr[pos] == 0) ! 345: goto endofline; ! 346: ! 347: /* parse the source address */ ! 348: usesrc = 1; ! 349: switch (opcstr[pos++]) { ! 350: case 'D': ! 351: srcmode = Dreg; ! 352: switch (opcstr[pos++]) { ! 353: case 'r': srcreg = bitval[bitr]; srcgather = 1; srcpos = bitpos[bitr]; break; ! 354: case 'R': srcreg = bitval[bitR]; srcgather = 1; srcpos = bitpos[bitR]; break; ! 355: default: abort(); ! 356: } ! 357: break; ! 358: case 'A': ! 359: srcmode = Areg; ! 360: switch (opcstr[pos++]) { ! 361: case 'r': srcreg = bitval[bitr]; srcgather = 1; srcpos = bitpos[bitr]; break; ! 362: case 'R': srcreg = bitval[bitR]; srcgather = 1; srcpos = bitpos[bitR]; break; ! 363: default: abort(); ! 364: } ! 365: switch (opcstr[pos]) { ! 366: case 'p': srcmode = Apdi; pos++; break; ! 367: case 'P': srcmode = Aipi; pos++; break; ! 368: case 'a': srcmode = Aind; pos++; break; ! 369: } ! 370: break; ! 371: case 'L': ! 372: srcmode = absl; ! 373: break; ! 374: case '#': ! 375: switch (opcstr[pos++]) { ! 376: case 'z': srcmode = imm; break; ! 377: case '0': srcmode = imm0; break; ! 378: case '1': srcmode = imm1; break; ! 379: case '2': srcmode = imm2; break; ! 380: case 'i': srcmode = immi; srcreg = (uae_s32)(uae_s8)bitval[biti]; ! 381: if (CPU_EMU_SIZE < 4) { ! 382: /* Used for branch instructions */ ! 383: srctype = 1; ! 384: srcgather = 1; ! 385: srcpos = bitpos[biti]; ! 386: } ! 387: break; ! 388: case 'j': srcmode = immi; srcreg = bitval[bitj]; ! 389: if (CPU_EMU_SIZE < 3) { ! 390: /* 1..8 for ADDQ/SUBQ and rotshi insns */ ! 391: srcgather = 1; ! 392: srctype = 3; ! 393: srcpos = bitpos[bitj]; ! 394: } ! 395: break; ! 396: case 'J': srcmode = immi; srcreg = bitval[bitJ]; ! 397: if (CPU_EMU_SIZE < 5) { ! 398: /* 0..15 */ ! 399: srcgather = 1; ! 400: srctype = 2; ! 401: srcpos = bitpos[bitJ]; ! 402: } ! 403: break; ! 404: case 'k': srcmode = immi; srcreg = bitval[bitk]; ! 405: if (CPU_EMU_SIZE < 3) { ! 406: srcgather = 1; ! 407: srctype = 4; ! 408: srcpos = bitpos[bitk]; ! 409: } ! 410: break; ! 411: case 'K': srcmode = immi; srcreg = bitval[bitK]; ! 412: if (CPU_EMU_SIZE < 5) { ! 413: /* 0..15 */ ! 414: srcgather = 1; ! 415: srctype = 5; ! 416: srcpos = bitpos[bitK]; ! 417: } ! 418: break; ! 419: case 'p': srcmode = immi; srcreg = bitval[bitK]; ! 420: if (CPU_EMU_SIZE < 5) { ! 421: /* 0..3 */ ! 422: srcgather = 1; ! 423: srctype = 7; ! 424: srcpos = bitpos[bitp]; ! 425: } ! 426: break; ! 427: default: abort(); ! 428: } ! 429: break; ! 430: case 'd': ! 431: srcreg = bitval[bitD]; ! 432: srcmode = mode_from_mr(bitval[bitd],bitval[bitD]); ! 433: if (srcmode == am_illg) ! 434: continue; ! 435: if (CPU_EMU_SIZE < 2 && ! 436: (srcmode == Areg || srcmode == Dreg || srcmode == Aind ! 437: || srcmode == Ad16 || srcmode == Ad8r || srcmode == Aipi ! 438: || srcmode == Apdi)) ! 439: { ! 440: srcgather = 1; srcpos = bitpos[bitD]; ! 441: } ! 442: if (opcstr[pos] == '[') { ! 443: pos++; ! 444: if (opcstr[pos] == '!') { ! 445: /* exclusion */ ! 446: do { ! 447: pos++; ! 448: if (mode_from_str(opcstr+pos) == srcmode) ! 449: goto nomatch; ! 450: pos += 4; ! 451: } while (opcstr[pos] == ','); ! 452: pos++; ! 453: } else { ! 454: if (opcstr[pos+4] == '-') { ! 455: /* replacement */ ! 456: if (mode_from_str(opcstr+pos) == srcmode) ! 457: srcmode = mode_from_str(opcstr+pos+5); ! 458: else ! 459: goto nomatch; ! 460: pos += 10; ! 461: } else { ! 462: /* normal */ ! 463: while(mode_from_str(opcstr+pos) != srcmode) { ! 464: pos += 4; ! 465: if (opcstr[pos] == ']') ! 466: goto nomatch; ! 467: pos++; ! 468: } ! 469: while(opcstr[pos] != ']') pos++; ! 470: pos++; ! 471: break; ! 472: } ! 473: } ! 474: } ! 475: /* Some addressing modes are invalid as destination */ ! 476: if (srcmode == imm || srcmode == PC16 || srcmode == PC8r) ! 477: goto nomatch; ! 478: break; ! 479: case 's': ! 480: srcreg = bitval[bitS]; ! 481: srcmode = mode_from_mr(bitval[bits],bitval[bitS]); ! 482: ! 483: if (srcmode == am_illg) ! 484: continue; ! 485: if (CPU_EMU_SIZE < 2 && ! 486: (srcmode == Areg || srcmode == Dreg || srcmode == Aind ! 487: || srcmode == Ad16 || srcmode == Ad8r || srcmode == Aipi ! 488: || srcmode == Apdi)) ! 489: { ! 490: srcgather = 1; srcpos = bitpos[bitS]; ! 491: } ! 492: if (opcstr[pos] == '[') { ! 493: pos++; ! 494: if (opcstr[pos] == '!') { ! 495: /* exclusion */ ! 496: do { ! 497: pos++; ! 498: if (mode_from_str(opcstr+pos) == srcmode) ! 499: goto nomatch; ! 500: pos += 4; ! 501: } while (opcstr[pos] == ','); ! 502: pos++; ! 503: } else { ! 504: if (opcstr[pos+4] == '-') { ! 505: /* replacement */ ! 506: if (mode_from_str(opcstr+pos) == srcmode) ! 507: srcmode = mode_from_str(opcstr+pos+5); ! 508: else ! 509: goto nomatch; ! 510: pos += 10; ! 511: } else { ! 512: /* normal */ ! 513: while(mode_from_str(opcstr+pos) != srcmode) { ! 514: pos += 4; ! 515: if (opcstr[pos] == ']') ! 516: goto nomatch; ! 517: pos++; ! 518: } ! 519: while(opcstr[pos] != ']') pos++; ! 520: pos++; ! 521: } ! 522: } ! 523: } ! 524: break; ! 525: default: abort(); ! 526: } ! 527: /* safety check - might have changed */ ! 528: if (srcmode != Areg && srcmode != Dreg && srcmode != Aind ! 529: && srcmode != Ad16 && srcmode != Ad8r && srcmode != Aipi ! 530: && srcmode != Apdi && srcmode != immi) ! 531: { ! 532: srcgather = 0; ! 533: } ! 534: if (srcmode == Areg && sz == sz_byte) ! 535: goto nomatch; ! 536: ! 537: if (opcstr[pos] != ',') ! 538: goto endofline; ! 539: pos++; ! 540: ! 541: /* parse the destination address */ ! 542: usedst = 1; ! 543: switch (opcstr[pos++]) { ! 544: case 'D': ! 545: destmode = Dreg; ! 546: switch (opcstr[pos++]) { ! 547: case 'r': destreg = bitval[bitr]; dstgather = 1; dstpos = bitpos[bitr]; break; ! 548: case 'R': destreg = bitval[bitR]; dstgather = 1; dstpos = bitpos[bitR]; break; ! 549: default: abort(); ! 550: } ! 551: if (dstpos < 0 || dstpos >= 32) ! 552: abort (); ! 553: break; ! 554: case 'A': ! 555: destmode = Areg; ! 556: switch (opcstr[pos++]) { ! 557: case 'r': destreg = bitval[bitr]; dstgather = 1; dstpos = bitpos[bitr]; break; ! 558: case 'R': destreg = bitval[bitR]; dstgather = 1; dstpos = bitpos[bitR]; break; ! 559: case 'x': destreg = 0; dstgather = 0; dstpos = 0; break; ! 560: default: abort(); ! 561: } ! 562: if (dstpos < 0 || dstpos >= 32) ! 563: abort (); ! 564: switch (opcstr[pos]) { ! 565: case 'p': destmode = Apdi; pos++; break; ! 566: case 'P': destmode = Aipi; pos++; break; ! 567: } ! 568: break; ! 569: case 'L': ! 570: destmode = absl; ! 571: break; ! 572: case '#': ! 573: switch (opcstr[pos++]) { ! 574: case 'z': destmode = imm; break; ! 575: case '0': destmode = imm0; break; ! 576: case '1': destmode = imm1; break; ! 577: case '2': destmode = imm2; break; ! 578: case 'i': destmode = immi; destreg = (uae_s32)(uae_s8)bitval[biti]; break; ! 579: case 'j': destmode = immi; destreg = bitval[bitj]; break; ! 580: case 'J': destmode = immi; destreg = bitval[bitJ]; break; ! 581: case 'k': destmode = immi; destreg = bitval[bitk]; break; ! 582: case 'K': destmode = immi; destreg = bitval[bitK]; break; ! 583: default: abort(); ! 584: } ! 585: break; ! 586: case 'd': ! 587: destreg = bitval[bitD]; ! 588: destmode = mode_from_mr(bitval[bitd],bitval[bitD]); ! 589: if (destmode == am_illg) ! 590: continue; ! 591: if (CPU_EMU_SIZE < 1 && ! 592: (destmode == Areg || destmode == Dreg || destmode == Aind ! 593: || destmode == Ad16 || destmode == Ad8r || destmode == Aipi ! 594: || destmode == Apdi)) ! 595: { ! 596: dstgather = 1; dstpos = bitpos[bitD]; ! 597: } ! 598: ! 599: if (opcstr[pos] == '[') { ! 600: pos++; ! 601: if (opcstr[pos] == '!') { ! 602: /* exclusion */ ! 603: do { ! 604: pos++; ! 605: if (mode_from_str(opcstr+pos) == destmode) ! 606: goto nomatch; ! 607: pos += 4; ! 608: } while (opcstr[pos] == ','); ! 609: pos++; ! 610: } else { ! 611: if (opcstr[pos+4] == '-') { ! 612: /* replacement */ ! 613: if (mode_from_str(opcstr+pos) == destmode) ! 614: destmode = mode_from_str(opcstr+pos+5); ! 615: else ! 616: goto nomatch; ! 617: pos += 10; ! 618: } else { ! 619: /* normal */ ! 620: while(mode_from_str(opcstr+pos) != destmode) { ! 621: pos += 4; ! 622: if (opcstr[pos] == ']') ! 623: goto nomatch; ! 624: pos++; ! 625: } ! 626: while(opcstr[pos] != ']') pos++; ! 627: pos++; ! 628: break; ! 629: } ! 630: } ! 631: } ! 632: /* Some addressing modes are invalid as destination */ ! 633: if (destmode == imm || destmode == PC16 || destmode == PC8r) ! 634: goto nomatch; ! 635: break; ! 636: case 's': ! 637: destreg = bitval[bitS]; ! 638: destmode = mode_from_mr(bitval[bits],bitval[bitS]); ! 639: ! 640: if (destmode == am_illg) ! 641: continue; ! 642: if (CPU_EMU_SIZE < 1 && ! 643: (destmode == Areg || destmode == Dreg || destmode == Aind ! 644: || destmode == Ad16 || destmode == Ad8r || destmode == Aipi ! 645: || destmode == Apdi)) ! 646: { ! 647: dstgather = 1; dstpos = bitpos[bitS]; ! 648: } ! 649: ! 650: if (opcstr[pos] == '[') { ! 651: pos++; ! 652: if (opcstr[pos] == '!') { ! 653: /* exclusion */ ! 654: do { ! 655: pos++; ! 656: if (mode_from_str(opcstr+pos) == destmode) ! 657: goto nomatch; ! 658: pos += 4; ! 659: } while (opcstr[pos] == ','); ! 660: pos++; ! 661: } else { ! 662: if (opcstr[pos+4] == '-') { ! 663: /* replacement */ ! 664: if (mode_from_str(opcstr+pos) == destmode) ! 665: destmode = mode_from_str(opcstr+pos+5); ! 666: else ! 667: goto nomatch; ! 668: pos += 10; ! 669: } else { ! 670: /* normal */ ! 671: while(mode_from_str(opcstr+pos) != destmode) { ! 672: pos += 4; ! 673: if (opcstr[pos] == ']') ! 674: goto nomatch; ! 675: pos++; ! 676: } ! 677: while(opcstr[pos] != ']') pos++; ! 678: pos++; ! 679: } ! 680: } ! 681: } ! 682: break; ! 683: default: abort(); ! 684: } ! 685: /* safety check - might have changed */ ! 686: if (destmode != Areg && destmode != Dreg && destmode != Aind ! 687: && destmode != Ad16 && destmode != Ad8r && destmode != Aipi ! 688: && destmode != Apdi) ! 689: { ! 690: dstgather = 0; ! 691: } ! 692: ! 693: if (destmode == Areg && sz == sz_byte) ! 694: goto nomatch; ! 695: #if 0 ! 696: if (sz == sz_byte && (destmode == Aipi || destmode == Apdi)) { ! 697: dstgather = 0; ! 698: } ! 699: #endif ! 700: endofline: ! 701: /* now, we have a match */ ! 702: if (table68k[opc].mnemo != i_ILLG) ! 703: ;//write_log (_T("Double match: %x: %s\n"), opc, opcstr); ! 704: if (find == -1) { ! 705: for (find = 0;; find++) { ! 706: if (_tcscmp (mnemonic, lookuptab[find].name) == 0) { ! 707: table68k[opc].mnemo = lookuptab[find].mnemo; ! 708: break; ! 709: } ! 710: if (_tcslen (lookuptab[find].name) == 0) ! 711: abort(); ! 712: } ! 713: } ! 714: else { ! 715: table68k[opc].mnemo = lookuptab[find].mnemo; ! 716: } ! 717: table68k[opc].cc = bitval[bitc]; ! 718: mnemo = table68k[opc].mnemo; ! 719: if (mnemo == i_BTST ! 720: || mnemo == i_BSET ! 721: || mnemo == i_BCLR ! 722: || mnemo == i_BCHG) ! 723: { ! 724: sz = destmode == Dreg ? sz_long : sz_byte; ! 725: unsized = 0; ! 726: } ! 727: if (mnemo == i_JSR || mnemo == i_JMP) { ! 728: unsized = 1; ! 729: } ! 730: ! 731: table68k[opc].size = sz; ! 732: table68k[opc].unsized = unsized; ! 733: table68k[opc].sduse = id.sduse; ! 734: table68k[opc].sreg = srcreg; ! 735: table68k[opc].dreg = destreg; ! 736: table68k[opc].smode = srcmode; ! 737: table68k[opc].dmode = destmode; ! 738: table68k[opc].spos = srcgather ? srcpos : -1; ! 739: table68k[opc].dpos = dstgather ? dstpos : -1; ! 740: table68k[opc].suse = usesrc; ! 741: table68k[opc].duse = usedst; ! 742: table68k[opc].stype = srctype; ! 743: table68k[opc].plev = id.plevel; ! 744: table68k[opc].clev = id.cpulevel; ! 745: table68k[opc].unimpclev = id.unimpcpulevel; ! 746: table68k[opc].head = id.head; ! 747: table68k[opc].tail = id.tail; ! 748: table68k[opc].clocks = id.clocks; ! 749: table68k[opc].fetchmode = id.fetchmode; ! 750: ! 751: #if 0 ! 752: for (i = 0; i < 5; i++) { ! 753: table68k[opc].flaginfo[i].flagset = id.flaginfo[i].flagset; ! 754: table68k[opc].flaginfo[i].flaguse = id.flaginfo[i].flaguse; ! 755: } ! 756: #endif ! 757: table68k[opc].flagdead = flagdead; ! 758: table68k[opc].flaglive = flaglive; ! 759: table68k[opc].isjmp = isjmp; ! 760: nomatch: ! 761: /* FOO! */; ! 762: } ! 763: } ! 764: ! 765: ! 766: void read_table68k (void) ! 767: { ! 768: int i; ! 769: ! 770: free (table68k); ! 771: table68k = xmalloc (struct instr, 65536); ! 772: for (i = 0; i < 65536; i++) { ! 773: table68k[i].mnemo = i_ILLG; ! 774: table68k[i].handler = -1; ! 775: } ! 776: for (i = 0; i < n_defs68k; i++) { ! 777: build_insn (i); ! 778: } ! 779: } ! 780: ! 781: static int imismatch; ! 782: ! 783: static void handle_merges (long int opcode) ! 784: { ! 785: uae_u16 smsk; ! 786: uae_u16 dmsk; ! 787: int sbitdst, dstend; ! 788: int srcreg, dstreg; ! 789: ! 790: if (table68k[opcode].spos == -1) { ! 791: sbitdst = 1; smsk = 0; ! 792: } else { ! 793: switch (table68k[opcode].stype) { ! 794: case 0: ! 795: smsk = 7; sbitdst = 8; break; ! 796: case 1: ! 797: smsk = 255; sbitdst = 256; break; ! 798: case 2: ! 799: smsk = 15; sbitdst = 16; break; ! 800: case 3: ! 801: smsk = 7; sbitdst = 8; break; ! 802: case 4: ! 803: smsk = 7; sbitdst = 8; break; ! 804: case 5: ! 805: smsk = 63; sbitdst = 64; break; ! 806: case 7: ! 807: smsk = 3; sbitdst = 4; break; ! 808: default: ! 809: smsk = 0; sbitdst = 0; ! 810: abort(); ! 811: break; ! 812: } ! 813: smsk <<= table68k[opcode].spos; ! 814: } ! 815: if (table68k[opcode].dpos == -1) { ! 816: dstend = 1; dmsk = 0; ! 817: } else { ! 818: dmsk = 7 << table68k[opcode].dpos; ! 819: dstend = 8; ! 820: } ! 821: for (srcreg=0; srcreg < sbitdst; srcreg++) { ! 822: for (dstreg=0; dstreg < dstend; dstreg++) { ! 823: uae_u16 code = (uae_u16)opcode; ! 824: ! 825: code = (code & ~smsk) | (srcreg << table68k[opcode].spos); ! 826: code = (code & ~dmsk) | (dstreg << table68k[opcode].dpos); ! 827: ! 828: /* Check whether this is in fact the same instruction. ! 829: * The instructions should never differ, except for the ! 830: * Bcc.(BW) case. */ ! 831: if (table68k[code].mnemo != table68k[opcode].mnemo ! 832: || table68k[code].size != table68k[opcode].size ! 833: || table68k[code].suse != table68k[opcode].suse ! 834: || table68k[code].duse != table68k[opcode].duse) ! 835: { ! 836: imismatch++; continue; ! 837: } ! 838: if (table68k[opcode].suse ! 839: && (table68k[opcode].spos != table68k[code].spos ! 840: || table68k[opcode].smode != table68k[code].smode ! 841: || table68k[opcode].stype != table68k[code].stype)) ! 842: { ! 843: imismatch++; continue; ! 844: } ! 845: if (table68k[opcode].duse ! 846: && (table68k[opcode].dpos != table68k[code].dpos ! 847: || table68k[opcode].dmode != table68k[code].dmode)) ! 848: { ! 849: imismatch++; continue; ! 850: } ! 851: ! 852: if (code != opcode) ! 853: table68k[code].handler = opcode; ! 854: } ! 855: } ! 856: } ! 857: ! 858: void do_merges (void) ! 859: { ! 860: long int opcode; ! 861: int nr = 0; ! 862: imismatch = 0; ! 863: for (opcode = 0; opcode < 65536; opcode++) { ! 864: if (table68k[opcode].handler != -1 || table68k[opcode].mnemo == i_ILLG) ! 865: continue; ! 866: nr++; ! 867: handle_merges (opcode); ! 868: } ! 869: nr_cpuop_funcs = nr; ! 870: } ! 871: ! 872: int get_no_mismatches (void) ! 873: { ! 874: return imismatch; ! 875: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.