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