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