|
|
1.1 root 1: /* 1.1.1.3 ! root 2: * UAE - The Un*x Amiga Emulator ! 3: * ! 4: * Read 68000 CPU specs from file "table68k" ! 5: * ! 6: * Copyright 1995,1996 Bernd Schmidt ! 7: */ 1.1 root 8: 9: #include "sysconfig.h" 10: #include "sysdeps.h" 11: #include <ctype.h> 1.1.1.3 ! root 12: #include <string.h> 1.1 root 13: 14: #include "readcpu.h" 15: 16: int nr_cpuop_funcs; 17: 18: struct mnemolookup lookuptab[] = { 1.1.1.3 ! root 19: { i_ILLG, _T("ILLEGAL") }, ! 20: { i_OR, _T("OR") }, ! 21: { i_CHK, _T("CHK") }, ! 22: { i_CHK2, _T("CHK2") }, ! 23: { i_AND, _T("AND") }, ! 24: { i_EOR, _T("EOR") }, ! 25: { i_ORSR, _T("ORSR") }, ! 26: { i_ANDSR, _T("ANDSR") }, ! 27: { i_EORSR, _T("EORSR") }, ! 28: { i_SUB, _T("SUB") }, ! 29: { i_SUBA, _T("SUBA") }, ! 30: { i_SUBX, _T("SUBX") }, ! 31: { i_SBCD, _T("SBCD") }, ! 32: { i_ADD, _T("ADD") }, ! 33: { i_ADDA, _T("ADDA") }, ! 34: { i_ADDX, _T("ADDX") }, ! 35: { i_ABCD, _T("ABCD") }, ! 36: { i_NEG, _T("NEG") }, ! 37: { i_NEGX, _T("NEGX") }, ! 38: { i_NBCD, _T("NBCD") }, ! 39: { i_CLR, _T("CLR") }, ! 40: { i_NOT, _T("NOT") }, ! 41: { i_TST, _T("TST") }, ! 42: { i_BTST, _T("BTST") }, ! 43: { i_BCHG, _T("BCHG") }, ! 44: { i_BCLR, _T("BCLR") }, ! 45: { i_BSET, _T("BSET") }, ! 46: { i_CMP, _T("CMP") }, ! 47: { i_CMPM, _T("CMPM") }, ! 48: { i_CMPA, _T("CMPA") }, ! 49: { i_MVPRM, _T("MVPRM") }, ! 50: { i_MVPMR, _T("MVPMR") }, ! 51: { i_MOVE, _T("MOVE") }, ! 52: { i_MOVEA, _T("MOVEA") }, ! 53: { i_MVSR2, _T("MVSR2") }, ! 54: { i_MV2SR, _T("MV2SR") }, ! 55: { i_SWAP, _T("SWAP") }, ! 56: { i_EXG, _T("EXG") }, ! 57: { i_EXT, _T("EXT") }, ! 58: { i_MVMEL, _T("MVMEL"), _T("MOVEM") }, ! 59: { i_MVMLE, _T("MVMLE"), _T("MOVEM") }, ! 60: { i_TRAP, _T("TRAP") }, ! 61: { i_MVR2USP, _T("MVR2USP") }, ! 62: { i_MVUSP2R, _T("MVUSP2R") }, ! 63: { i_NOP, _T("NOP") }, ! 64: { i_RESET, _T("RESET") }, ! 65: { i_RTE, _T("RTE") }, ! 66: { i_RTD, _T("RTD") }, ! 67: { i_LINK, _T("LINK") }, ! 68: { i_UNLK, _T("UNLK") }, ! 69: { i_RTS, _T("RTS") }, ! 70: { i_STOP, _T("STOP") }, ! 71: { i_TRAPV, _T("TRAPV") }, ! 72: { i_RTR, _T("RTR") }, ! 73: { i_JSR, _T("JSR") }, ! 74: { i_JMP, _T("JMP") }, ! 75: { i_BSR, _T("BSR") }, ! 76: { i_Bcc, _T("Bcc") }, ! 77: { i_LEA, _T("LEA") }, ! 78: { i_PEA, _T("PEA") }, ! 79: { i_DBcc, _T("DBcc") }, ! 80: { i_Scc, _T("Scc") }, ! 81: { i_DIVU, _T("DIVU") }, ! 82: { i_DIVS, _T("DIVS") }, ! 83: { i_MULU, _T("MULU") }, ! 84: { i_MULS, _T("MULS") }, ! 85: { i_ASR, _T("ASR") }, ! 86: { i_ASL, _T("ASL") }, ! 87: { i_LSR, _T("LSR") }, ! 88: { i_LSL, _T("LSL") }, ! 89: { i_ROL, _T("ROL") }, ! 90: { i_ROR, _T("ROR") }, ! 91: { i_ROXL, _T("ROXL") }, ! 92: { i_ROXR, _T("ROXR") }, ! 93: { i_ASRW, _T("ASRW") }, ! 94: { i_ASLW, _T("ASLW") }, ! 95: { i_LSRW, _T("LSRW") }, ! 96: { i_LSLW, _T("LSLW") }, ! 97: { i_ROLW, _T("ROLW") }, ! 98: { i_RORW, _T("RORW") }, ! 99: { i_ROXLW, _T("ROXLW") }, ! 100: { i_ROXRW, _T("ROXRW") }, ! 101: ! 102: { i_MOVE2C, _T("MOVE2C"), _T("MOVEC") }, ! 103: { i_MOVEC2, _T("MOVEC2"), _T("MOVEC") }, ! 104: { i_CAS, _T("CAS") }, ! 105: { i_CAS2, _T("CAS2") }, ! 106: { i_MULL, _T("MULL") }, ! 107: { i_DIVL, _T("DIVL") }, ! 108: { i_BFTST, _T("BFTST") }, ! 109: { i_BFEXTU, _T("BFEXTU") }, ! 110: { i_BFCHG, _T("BFCHG") }, ! 111: { i_BFEXTS, _T("BFEXTS") }, ! 112: { i_BFCLR, _T("BFCLR") }, ! 113: { i_BFFFO, _T("BFFFO") }, ! 114: { i_BFSET, _T("BFSET") }, ! 115: { i_BFINS, _T("BFINS") }, ! 116: { i_PACK, _T("PACK") }, ! 117: { i_UNPK, _T("UNPK") }, ! 118: { i_TAS, _T("TAS") }, ! 119: { i_BKPT, _T("BKPT") }, ! 120: { i_CALLM, _T("CALLM") }, ! 121: { i_RTM, _T("RTM") }, ! 122: { i_TRAPcc, _T("TRAPcc") }, ! 123: { i_MOVES, _T("MOVES") }, ! 124: { i_FPP, _T("FPP") }, ! 125: { i_FDBcc, _T("FDBcc") }, ! 126: { i_FScc, _T("FScc") }, ! 127: { i_FTRAPcc, _T("FTRAPcc") }, ! 128: { i_FBcc, _T("FBcc") }, ! 129: { i_FBcc, _T("FBcc") }, ! 130: { i_FSAVE, _T("FSAVE") }, ! 131: { i_FRESTORE, _T("FRESTORE") }, ! 132: ! 133: { i_CINVL, _T("CINVL") }, ! 134: { i_CINVP, _T("CINVP") }, ! 135: { i_CINVA, _T("CINVA") }, ! 136: { i_CPUSHL, _T("CPUSHL") }, ! 137: { i_CPUSHP, _T("CPUSHP") }, ! 138: { i_CPUSHA, _T("CPUSHA") }, ! 139: { i_MOVE16, _T("MOVE16") }, ! 140: ! 141: { i_MMUOP030, _T("MMUOP030") }, ! 142: { i_PFLUSHN, _T("PFLUSHN") }, ! 143: { i_PFLUSH, _T("PFLUSH") }, ! 144: { i_PFLUSHAN, _T("PFLUSHAN") }, ! 145: { i_PFLUSHA, _T("PFLUSHA") }, ! 146: ! 147: { i_PLPAR, _T("PLPAR") }, ! 148: { i_PLPAW, _T("PLPAW") }, ! 149: { i_PTESTR, _T("PTESTR") }, ! 150: { i_PTESTW, _T("PTESTW") }, ! 151: ! 152: { i_LPSTOP, _T("LPSTOP") }, ! 153: { i_ILLG, _T("") }, 1.1 root 154: }; 155: 156: struct instr *table68k; 157: 158: static amodes mode_from_str (const TCHAR *str) 159: { 1.1.1.3 ! root 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; 1.1 root 174: } 175: 176: STATIC_INLINE amodes mode_from_mr (int mode, int reg) 177: { 1.1.1.3 ! root 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; 1.1 root 200: } 201: 202: static void build_insn (int insn) 203: { 1.1.1.3 ! root 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: 1.1 root 234: out1: 1.1.1.3 ! root 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; 1.1.1.2 root 256: int unsized = 1; 1.1.1.3 ! root 257: TCHAR mnemonic[10]; 1.1.1.2 root 258: int mnemo; 1.1.1.3 ! root 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++; 1.1.1.2 root 307: unsized = 0; 1.1.1.3 ! root 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; 1.1 root 695: #if 0 1.1.1.3 ! root 696: if (sz == sz_byte && (destmode == Aipi || destmode == Apdi)) { ! 697: dstgather = 0; ! 698: } 1.1 root 699: #endif 1.1.1.3 ! root 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]; 1.1.1.2 root 718: mnemo = table68k[opc].mnemo; 719: if (mnemo == i_BTST 720: || mnemo == i_BSET 721: || mnemo == i_BCLR 722: || mnemo == i_BCHG) 723: { 1.1.1.3 ! root 724: sz = destmode == Dreg ? sz_long : sz_byte; 1.1.1.2 root 725: unsized = 0; 1.1.1.3 ! root 726: } 1.1.1.2 root 727: if (mnemo == i_JSR || mnemo == i_JMP) { 728: unsized = 1; 729: } 730: 1.1.1.3 ! root 731: table68k[opc].size = sz; 1.1.1.2 root 732: table68k[opc].unsized = unsized; 1.1.1.3 ! root 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: 1.1 root 751: #if 0 1.1.1.3 ! root 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: } 1.1 root 756: #endif 1.1.1.3 ! root 757: table68k[opc].flagdead = flagdead; ! 758: table68k[opc].flaglive = flaglive; ! 759: table68k[opc].isjmp = isjmp; ! 760: nomatch: ! 761: /* FOO! */; ! 762: } 1.1 root 763: } 764: 765: 766: void read_table68k (void) 767: { 1.1.1.3 ! root 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: } 1.1 root 779: } 780: 781: static int imismatch; 782: 783: static void handle_merges (long int opcode) 784: { 1.1.1.3 ! root 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: } 1.1 root 856: } 857: 858: void do_merges (void) 859: { 1.1.1.3 ! root 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; 1.1 root 870: } 871: 872: int get_no_mismatches (void) 873: { 1.1.1.3 ! root 874: return imismatch; 1.1 root 875: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.