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