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