|
|
1.1 root 1: /* 1.1.1.3 ! root 2: * UAE - The Un*x Amiga Emulator - CPU core 1.1 root 3: * 4: * Read 68000 CPU specs from file "table68k" 5: * 6: * Copyright 1995,1996 Bernd Schmidt 1.1.1.3 ! root 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. 1.1 root 12: */ 1.1.1.3 ! root 13: static char rcsid[] = "Hatari $Id: readcpu.c,v 1.3 2003/03/03 18:40:34 thothy Exp $"; 1.1 root 14: 15: #include <ctype.h> 1.1.1.2 root 16: #include <string.h> 17: 1.1 root 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_BFTST, "BFTST" }, 113: { i_BFEXTU, "BFEXTU" }, 114: { i_BFCHG, "BFCHG" }, 115: { i_BFEXTS, "BFEXTS" }, 116: { i_BFCLR, "BFCLR" }, 117: { i_BFFFO, "BFFFO" }, 118: { i_BFSET, "BFSET" }, 119: { i_BFINS, "BFINS" }, 120: { i_PACK, "PACK" }, 121: { i_UNPK, "UNPK" }, 122: { i_TAS, "TAS" }, 123: { i_BKPT, "BKPT" }, 124: { i_CALLM, "CALLM" }, 125: { i_RTM, "RTM" }, 126: { i_TRAPcc, "TRAPcc" }, 127: { i_MOVES, "MOVES" }, 128: { i_FPP, "FPP" }, 129: { i_FDBcc, "FDBcc" }, 130: { i_FScc, "FScc" }, 131: { i_FTRAPcc, "FTRAPcc" }, 132: { i_FBcc, "FBcc" }, 133: { i_FBcc, "FBcc" }, 134: { i_FSAVE, "FSAVE" }, 135: { i_FRESTORE, "FRESTORE" }, 136: 137: { i_CINVL, "CINVL" }, 138: { i_CINVP, "CINVP" }, 139: { i_CINVA, "CINVA" }, 140: { i_CPUSHL, "CPUSHL" }, 141: { i_CPUSHP, "CPUSHP" }, 142: { i_CPUSHA, "CPUSHA" }, 143: { i_MOVE16, "MOVE16" }, 144: 145: { i_MMUOP, "MMUOP" }, 146: { i_ILLG, "" }, 147: }; 148: 149: struct instr *table68k; 150: 151: STATIC_INLINE amodes mode_from_str (const char *str) 152: { 153: if (strncmp (str, "Dreg", 4) == 0) return Dreg; 154: if (strncmp (str, "Areg", 4) == 0) return Areg; 155: if (strncmp (str, "Aind", 4) == 0) return Aind; 156: if (strncmp (str, "Apdi", 4) == 0) return Apdi; 157: if (strncmp (str, "Aipi", 4) == 0) return Aipi; 158: if (strncmp (str, "Ad16", 4) == 0) return Ad16; 159: if (strncmp (str, "Ad8r", 4) == 0) return Ad8r; 160: if (strncmp (str, "absw", 4) == 0) return absw; 161: if (strncmp (str, "absl", 4) == 0) return absl; 162: if (strncmp (str, "PC16", 4) == 0) return PC16; 163: if (strncmp (str, "PC8r", 4) == 0) return PC8r; 164: if (strncmp (str, "Immd", 4) == 0) return imm; 165: abort (); 166: return 0; 167: } 168: 169: STATIC_INLINE amodes mode_from_mr (int mode, int reg) 170: { 171: switch (mode) { 172: case 0: return Dreg; 173: case 1: return Areg; 174: case 2: return Aind; 175: case 3: return Aipi; 176: case 4: return Apdi; 177: case 5: return Ad16; 178: case 6: return Ad8r; 179: case 7: 180: switch (reg) { 181: case 0: return absw; 182: case 1: return absl; 183: case 2: return PC16; 184: case 3: return PC8r; 185: case 4: return imm; 186: case 5: 187: case 6: 188: case 7: return am_illg; 189: } 190: } 191: abort (); 192: return 0; 193: } 194: 195: static void build_insn (int insn) 196: { 197: int find = -1; 198: int variants; 1.1.1.3 ! root 199: int isjmp = 0; 1.1 root 200: struct instr_def id; 201: const char *opcstr; 202: int i; 203: 204: int flaglive = 0, flagdead = 0; 205: 206: id = defs68k[insn]; 207: 1.1.1.3 ! root 208: /* Note: We treat anything with unknown flags as a jump. That ! 209: is overkill, but "the programmer" was lazy quite often, and ! 210: *this* programmer can't be bothered to work out what can and ! 211: can't trap. Usually, this will be overwritten with the gencomp ! 212: based information, anyway. */ ! 213: 1.1 root 214: for (i = 0; i < 5; i++) { 215: switch (id.flaginfo[i].flagset){ 216: case fa_unset: break; 1.1.1.3 ! root 217: case fa_isjmp: isjmp = 1; break; ! 218: case fa_isbranch: isjmp = 1; break; 1.1 root 219: case fa_zero: flagdead |= 1 << i; break; 220: case fa_one: flagdead |= 1 << i; break; 221: case fa_dontcare: flagdead |= 1 << i; break; 1.1.1.3 ! root 222: case fa_unknown: isjmp = 1; flagdead = -1; goto out1; 1.1 root 223: case fa_set: flagdead |= 1 << i; break; 224: } 225: } 226: 1.1.1.3 ! root 227: out1: 1.1 root 228: for (i = 0; i < 5; i++) { 229: switch (id.flaginfo[i].flaguse) { 230: case fu_unused: break; 1.1.1.3 ! root 231: case fu_isjmp: isjmp = 1; flaglive |= 1 << i; break; ! 232: case fu_maybecc: isjmp = 1; flaglive |= 1 << i; break; ! 233: case fu_unknown: isjmp = 1; flaglive |= 1 << i; break; 1.1 root 234: case fu_used: flaglive |= 1 << i; break; 235: } 236: } 237: 238: opcstr = id.opcstr; 239: for (variants = 0; variants < (1 << id.n_variable); variants++) { 240: int bitcnt[lastbit]; 241: int bitval[lastbit]; 242: int bitpos[lastbit]; 243: int i; 244: uae_u16 opc = id.bits; 245: uae_u16 msk, vmsk; 246: int pos = 0; 247: int mnp = 0; 248: int bitno = 0; 249: char mnemonic[10]; 250: 251: wordsizes sz = sz_long; 252: int srcgather = 0, dstgather = 0; 253: int usesrc = 0, usedst = 0; 254: int srctype = 0; 255: int srcpos = -1, dstpos = -1; 256: 257: amodes srcmode = am_unknown, destmode = am_unknown; 258: int srcreg = -1, destreg = -1; 259: 260: for (i = 0; i < lastbit; i++) 261: bitcnt[i] = bitval[i] = 0; 262: 263: vmsk = 1 << id.n_variable; 264: 265: for (i = 0, msk = 0x8000; i < 16; i++, msk >>= 1) { 266: if (!(msk & id.mask)) { 267: int currbit = id.bitpos[bitno++]; 268: int bit_set; 269: vmsk >>= 1; 270: bit_set = variants & vmsk ? 1 : 0; 271: if (bit_set) 272: opc |= msk; 273: bitpos[currbit] = 15 - i; 274: bitcnt[currbit]++; 275: bitval[currbit] <<= 1; 276: bitval[currbit] |= bit_set; 277: } 278: } 279: 280: if (bitval[bitj] == 0) bitval[bitj] = 8; 281: /* first check whether this one does not match after all */ 282: if (bitval[bitz] == 3 || bitval[bitC] == 1) 283: continue; 284: if (bitcnt[bitI] && (bitval[bitI] == 0x00 || bitval[bitI] == 0xff)) 285: continue; 286: 287: /* bitI and bitC get copied to biti and bitc */ 288: if (bitcnt[bitI]) { 289: bitval[biti] = bitval[bitI]; bitpos[biti] = bitpos[bitI]; 290: } 291: if (bitcnt[bitC]) 292: bitval[bitc] = bitval[bitC]; 293: 294: pos = 0; 295: while (opcstr[pos] && !isspace(opcstr[pos])) { 296: if (opcstr[pos] == '.') { 297: pos++; 298: switch (opcstr[pos]) { 299: 300: case 'B': sz = sz_byte; break; 301: case 'W': sz = sz_word; break; 302: case 'L': sz = sz_long; break; 303: case 'z': 304: switch (bitval[bitz]) { 305: case 0: sz = sz_byte; break; 306: case 1: sz = sz_word; break; 307: case 2: sz = sz_long; break; 308: default: abort(); 309: } 310: break; 311: default: abort(); 312: } 313: } else { 314: mnemonic[mnp] = opcstr[pos]; 315: if (mnemonic[mnp] == 'f') { 316: find = -1; 317: switch (bitval[bitf]) { 318: case 0: mnemonic[mnp] = 'R'; break; 319: case 1: mnemonic[mnp] = 'L'; break; 320: default: abort(); 321: } 322: } 323: mnp++; 324: } 325: pos++; 326: } 327: mnemonic[mnp] = 0; 328: 329: /* now, we have read the mnemonic and the size */ 330: while (opcstr[pos] && isspace(opcstr[pos])) 331: pos++; 332: 333: /* A goto a day keeps the D******a away. */ 334: if (opcstr[pos] == 0) 335: goto endofline; 336: 337: /* parse the source address */ 338: usesrc = 1; 339: switch (opcstr[pos++]) { 340: case 'D': 341: srcmode = Dreg; 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: 348: break; 349: case 'A': 350: srcmode = Areg; 351: switch (opcstr[pos++]) { 352: case 'r': srcreg = bitval[bitr]; srcgather = 1; srcpos = bitpos[bitr]; break; 353: case 'R': srcreg = bitval[bitR]; srcgather = 1; srcpos = bitpos[bitR]; break; 354: default: abort(); 355: } 356: switch (opcstr[pos]) { 357: case 'p': srcmode = Apdi; pos++; break; 358: case 'P': srcmode = Aipi; pos++; break; 359: } 360: break; 1.1.1.3 ! root 361: case 'L': ! 362: srcmode = absl; ! 363: break; 1.1 root 364: case '#': 365: switch (opcstr[pos++]) { 366: case 'z': srcmode = imm; break; 367: case '0': srcmode = imm0; break; 368: case '1': srcmode = imm1; break; 369: case '2': srcmode = imm2; break; 370: case 'i': srcmode = immi; srcreg = (uae_s32)(uae_s8)bitval[biti]; 371: if (CPU_EMU_SIZE < 4) { 372: /* Used for branch instructions */ 373: srctype = 1; 374: srcgather = 1; 375: srcpos = bitpos[biti]; 376: } 377: break; 378: case 'j': srcmode = immi; srcreg = bitval[bitj]; 379: if (CPU_EMU_SIZE < 3) { 380: /* 1..8 for ADDQ/SUBQ and rotshi insns */ 381: srcgather = 1; 382: srctype = 3; 383: srcpos = bitpos[bitj]; 384: } 385: break; 386: case 'J': srcmode = immi; srcreg = bitval[bitJ]; 387: if (CPU_EMU_SIZE < 5) { 388: /* 0..15 */ 389: srcgather = 1; 390: srctype = 2; 391: srcpos = bitpos[bitJ]; 392: } 393: break; 394: case 'k': srcmode = immi; srcreg = bitval[bitk]; 395: if (CPU_EMU_SIZE < 3) { 396: srcgather = 1; 397: srctype = 4; 398: srcpos = bitpos[bitk]; 399: } 400: break; 401: case 'K': srcmode = immi; srcreg = bitval[bitK]; 402: if (CPU_EMU_SIZE < 5) { 403: /* 0..15 */ 404: srcgather = 1; 405: srctype = 5; 406: srcpos = bitpos[bitK]; 407: } 408: break; 1.1.1.3 ! root 409: case 'p': srcmode = immi; srcreg = bitval[bitK]; ! 410: if (CPU_EMU_SIZE < 5) { ! 411: /* 0..3 */ ! 412: srcgather = 1; ! 413: srctype = 7; ! 414: srcpos = bitpos[bitp]; ! 415: } ! 416: break; 1.1 root 417: default: abort(); 418: } 419: break; 420: case 'd': 421: srcreg = bitval[bitD]; 422: srcmode = mode_from_mr(bitval[bitd],bitval[bitD]); 423: if (srcmode == am_illg) 424: continue; 425: if (CPU_EMU_SIZE < 2 && 426: (srcmode == Areg || srcmode == Dreg || srcmode == Aind 427: || srcmode == Ad16 || srcmode == Ad8r || srcmode == Aipi 428: || srcmode == Apdi)) 429: { 430: srcgather = 1; srcpos = bitpos[bitD]; 431: } 432: if (opcstr[pos] == '[') { 433: pos++; 434: if (opcstr[pos] == '!') { 435: /* exclusion */ 436: do { 437: pos++; 438: if (mode_from_str(opcstr+pos) == srcmode) 439: goto nomatch; 440: pos += 4; 441: } while (opcstr[pos] == ','); 442: pos++; 443: } else { 444: if (opcstr[pos+4] == '-') { 445: /* replacement */ 446: if (mode_from_str(opcstr+pos) == srcmode) 447: srcmode = mode_from_str(opcstr+pos+5); 448: else 449: goto nomatch; 450: pos += 10; 451: } else { 452: /* normal */ 453: while(mode_from_str(opcstr+pos) != srcmode) { 454: pos += 4; 455: if (opcstr[pos] == ']') 456: goto nomatch; 457: pos++; 458: } 459: while(opcstr[pos] != ']') pos++; 460: pos++; 461: break; 462: } 463: } 464: } 465: /* Some addressing modes are invalid as destination */ 466: if (srcmode == imm || srcmode == PC16 || srcmode == PC8r) 467: goto nomatch; 468: break; 469: case 's': 470: srcreg = bitval[bitS]; 471: srcmode = mode_from_mr(bitval[bits],bitval[bitS]); 472: 473: if (srcmode == am_illg) 474: continue; 475: if (CPU_EMU_SIZE < 2 && 476: (srcmode == Areg || srcmode == Dreg || srcmode == Aind 477: || srcmode == Ad16 || srcmode == Ad8r || srcmode == Aipi 478: || srcmode == Apdi)) 479: { 480: srcgather = 1; srcpos = bitpos[bitS]; 481: } 482: if (opcstr[pos] == '[') { 483: pos++; 484: if (opcstr[pos] == '!') { 485: /* exclusion */ 486: do { 487: pos++; 488: if (mode_from_str(opcstr+pos) == srcmode) 489: goto nomatch; 490: pos += 4; 491: } while (opcstr[pos] == ','); 492: pos++; 493: } else { 494: if (opcstr[pos+4] == '-') { 495: /* replacement */ 496: if (mode_from_str(opcstr+pos) == srcmode) 497: srcmode = mode_from_str(opcstr+pos+5); 498: else 499: goto nomatch; 500: pos += 10; 501: } else { 502: /* normal */ 503: while(mode_from_str(opcstr+pos) != srcmode) { 504: pos += 4; 505: if (opcstr[pos] == ']') 506: goto nomatch; 507: pos++; 508: } 509: while(opcstr[pos] != ']') pos++; 510: pos++; 511: } 512: } 513: } 514: break; 515: default: abort(); 516: } 517: /* safety check - might have changed */ 518: if (srcmode != Areg && srcmode != Dreg && srcmode != Aind 519: && srcmode != Ad16 && srcmode != Ad8r && srcmode != Aipi 520: && srcmode != Apdi && srcmode != immi) 521: { 522: srcgather = 0; 523: } 524: if (srcmode == Areg && sz == sz_byte) 525: goto nomatch; 526: 527: if (opcstr[pos] != ',') 528: goto endofline; 529: pos++; 530: 531: /* parse the destination address */ 532: usedst = 1; 533: switch (opcstr[pos++]) { 534: case 'D': 535: destmode = Dreg; 536: switch (opcstr[pos++]) { 537: case 'r': destreg = bitval[bitr]; dstgather = 1; dstpos = bitpos[bitr]; break; 538: case 'R': destreg = bitval[bitR]; dstgather = 1; dstpos = bitpos[bitR]; break; 539: default: abort(); 540: } 1.1.1.3 ! root 541: if (dstpos < 0 || dstpos >= 32) ! 542: abort (); 1.1 root 543: break; 544: case 'A': 545: destmode = Areg; 546: switch (opcstr[pos++]) { 547: case 'r': destreg = bitval[bitr]; dstgather = 1; dstpos = bitpos[bitr]; break; 548: case 'R': destreg = bitval[bitR]; dstgather = 1; dstpos = bitpos[bitR]; break; 1.1.1.3 ! root 549: case 'x': destreg = 0; dstgather = 0; dstpos = 0; break; 1.1 root 550: default: abort(); 551: } 1.1.1.3 ! root 552: if (dstpos < 0 || dstpos >= 32) ! 553: abort (); 1.1 root 554: switch (opcstr[pos]) { 555: case 'p': destmode = Apdi; pos++; break; 556: case 'P': destmode = Aipi; pos++; break; 557: } 558: break; 1.1.1.3 ! root 559: case 'L': ! 560: destmode = absl; ! 561: break; 1.1 root 562: case '#': 563: switch (opcstr[pos++]) { 564: case 'z': destmode = imm; break; 565: case '0': destmode = imm0; break; 566: case '1': destmode = imm1; break; 567: case '2': destmode = imm2; break; 568: case 'i': destmode = immi; destreg = (uae_s32)(uae_s8)bitval[biti]; break; 569: case 'j': destmode = immi; destreg = bitval[bitj]; break; 570: case 'J': destmode = immi; destreg = bitval[bitJ]; break; 571: case 'k': destmode = immi; destreg = bitval[bitk]; break; 572: case 'K': destmode = immi; destreg = bitval[bitK]; break; 573: default: abort(); 574: } 575: break; 576: case 'd': 577: destreg = bitval[bitD]; 578: destmode = mode_from_mr(bitval[bitd],bitval[bitD]); 579: if (destmode == am_illg) 580: continue; 581: if (CPU_EMU_SIZE < 1 && 582: (destmode == Areg || destmode == Dreg || destmode == Aind 583: || destmode == Ad16 || destmode == Ad8r || destmode == Aipi 584: || destmode == Apdi)) 585: { 586: dstgather = 1; dstpos = bitpos[bitD]; 587: } 588: 589: if (opcstr[pos] == '[') { 590: pos++; 591: if (opcstr[pos] == '!') { 592: /* exclusion */ 593: do { 594: pos++; 595: if (mode_from_str(opcstr+pos) == destmode) 596: goto nomatch; 597: pos += 4; 598: } while (opcstr[pos] == ','); 599: pos++; 600: } else { 601: if (opcstr[pos+4] == '-') { 602: /* replacement */ 603: if (mode_from_str(opcstr+pos) == destmode) 604: destmode = mode_from_str(opcstr+pos+5); 605: else 606: goto nomatch; 607: pos += 10; 608: } else { 609: /* normal */ 610: while(mode_from_str(opcstr+pos) != destmode) { 611: pos += 4; 612: if (opcstr[pos] == ']') 613: goto nomatch; 614: pos++; 615: } 616: while(opcstr[pos] != ']') pos++; 617: pos++; 618: break; 619: } 620: } 621: } 622: /* Some addressing modes are invalid as destination */ 623: if (destmode == imm || destmode == PC16 || destmode == PC8r) 624: goto nomatch; 625: break; 626: case 's': 627: destreg = bitval[bitS]; 628: destmode = mode_from_mr(bitval[bits],bitval[bitS]); 629: 630: if (destmode == am_illg) 631: continue; 632: if (CPU_EMU_SIZE < 1 && 633: (destmode == Areg || destmode == Dreg || destmode == Aind 634: || destmode == Ad16 || destmode == Ad8r || destmode == Aipi 635: || destmode == Apdi)) 636: { 637: dstgather = 1; dstpos = bitpos[bitS]; 638: } 639: 640: if (opcstr[pos] == '[') { 641: pos++; 642: if (opcstr[pos] == '!') { 643: /* exclusion */ 644: do { 645: pos++; 646: if (mode_from_str(opcstr+pos) == destmode) 647: goto nomatch; 648: pos += 4; 649: } while (opcstr[pos] == ','); 650: pos++; 651: } else { 652: if (opcstr[pos+4] == '-') { 653: /* replacement */ 654: if (mode_from_str(opcstr+pos) == destmode) 655: destmode = mode_from_str(opcstr+pos+5); 656: else 657: goto nomatch; 658: pos += 10; 659: } else { 660: /* normal */ 661: while(mode_from_str(opcstr+pos) != destmode) { 662: pos += 4; 663: if (opcstr[pos] == ']') 664: goto nomatch; 665: pos++; 666: } 667: while(opcstr[pos] != ']') pos++; 668: pos++; 669: } 670: } 671: } 672: break; 673: default: abort(); 674: } 675: /* safety check - might have changed */ 676: if (destmode != Areg && destmode != Dreg && destmode != Aind 677: && destmode != Ad16 && destmode != Ad8r && destmode != Aipi 678: && destmode != Apdi) 679: { 680: dstgather = 0; 681: } 682: 683: if (destmode == Areg && sz == sz_byte) 684: goto nomatch; 685: #if 0 686: if (sz == sz_byte && (destmode == Aipi || destmode == Apdi)) { 687: dstgather = 0; 688: } 689: #endif 690: endofline: 691: /* now, we have a match */ 692: if (table68k[opc].mnemo != i_ILLG) 693: fprintf(stderr, "Double match: %x: %s\n", opc, opcstr); 694: if (find == -1) { 695: for (find = 0;; find++) { 696: if (strcmp(mnemonic, lookuptab[find].name) == 0) { 697: table68k[opc].mnemo = lookuptab[find].mnemo; 698: break; 699: } 700: if (strlen(lookuptab[find].name) == 0) abort(); 701: } 702: } 703: else { 704: table68k[opc].mnemo = lookuptab[find].mnemo; 705: } 706: table68k[opc].cc = bitval[bitc]; 707: if (table68k[opc].mnemo == i_BTST 708: || table68k[opc].mnemo == i_BSET 709: || table68k[opc].mnemo == i_BCLR 710: || table68k[opc].mnemo == i_BCHG) 711: { 712: sz = destmode == Dreg ? sz_long : sz_byte; 713: } 714: table68k[opc].size = sz; 715: table68k[opc].sreg = srcreg; 716: table68k[opc].dreg = destreg; 717: table68k[opc].smode = srcmode; 718: table68k[opc].dmode = destmode; 719: table68k[opc].spos = srcgather ? srcpos : -1; 720: table68k[opc].dpos = dstgather ? dstpos : -1; 721: table68k[opc].suse = usesrc; 722: table68k[opc].duse = usedst; 723: table68k[opc].stype = srctype; 724: table68k[opc].plev = id.plevel; 725: table68k[opc].clev = id.cpulevel; 726: #if 0 727: for (i = 0; i < 5; i++) { 728: table68k[opc].flaginfo[i].flagset = id.flaginfo[i].flagset; 729: table68k[opc].flaginfo[i].flaguse = id.flaginfo[i].flaguse; 730: } 731: #endif 732: table68k[opc].flagdead = flagdead; 733: table68k[opc].flaglive = flaglive; 1.1.1.3 ! root 734: table68k[opc].isjmp = isjmp; ! 735: nomatch: 1.1 root 736: /* FOO! */; 737: } 738: } 739: 740: 741: void read_table68k (void) 742: { 743: int i; 744: 745: table68k = (struct instr *)malloc (65536 * sizeof (struct instr)); 746: for (i = 0; i < 65536; i++) { 747: table68k[i].mnemo = i_ILLG; 748: table68k[i].handler = -1; 749: } 750: for (i = 0; i < n_defs68k; i++) { 751: build_insn (i); 752: } 753: } 754: 755: static int mismatch; 756: 757: static void handle_merges (long int opcode) 758: { 759: uae_u16 smsk; 760: uae_u16 dmsk; 761: int sbitdst, dstend; 762: int srcreg, dstreg; 763: 764: if (table68k[opcode].spos == -1) { 765: sbitdst = 1; smsk = 0; 766: } else { 767: switch (table68k[opcode].stype) { 768: case 0: 769: smsk = 7; sbitdst = 8; break; 770: case 1: 771: smsk = 255; sbitdst = 256; break; 772: case 2: 773: smsk = 15; sbitdst = 16; break; 774: case 3: 775: smsk = 7; sbitdst = 8; break; 776: case 4: 777: smsk = 7; sbitdst = 8; break; 778: case 5: 779: smsk = 63; sbitdst = 64; break; 1.1.1.3 ! root 780: case 7: ! 781: smsk = 3; sbitdst = 4; break; 1.1 root 782: default: 783: smsk = 0; sbitdst = 0; 784: abort(); 785: break; 786: } 787: smsk <<= table68k[opcode].spos; 788: } 789: if (table68k[opcode].dpos == -1) { 790: dstend = 1; dmsk = 0; 791: } else { 792: dmsk = 7 << table68k[opcode].dpos; 793: dstend = 8; 794: } 795: for (srcreg=0; srcreg < sbitdst; srcreg++) { 796: for (dstreg=0; dstreg < dstend; dstreg++) { 797: uae_u16 code = opcode; 798: 799: code = (code & ~smsk) | (srcreg << table68k[opcode].spos); 800: code = (code & ~dmsk) | (dstreg << table68k[opcode].dpos); 801: 802: /* Check whether this is in fact the same instruction. 803: * The instructions should never differ, except for the 804: * Bcc.(BW) case. */ 805: if (table68k[code].mnemo != table68k[opcode].mnemo 806: || table68k[code].size != table68k[opcode].size 807: || table68k[code].suse != table68k[opcode].suse 808: || table68k[code].duse != table68k[opcode].duse) 809: { 810: mismatch++; continue; 811: } 812: if (table68k[opcode].suse 813: && (table68k[opcode].spos != table68k[code].spos 814: || table68k[opcode].smode != table68k[code].smode 815: || table68k[opcode].stype != table68k[code].stype)) 816: { 817: mismatch++; continue; 818: } 819: if (table68k[opcode].duse 820: && (table68k[opcode].dpos != table68k[code].dpos 821: || table68k[opcode].dmode != table68k[code].dmode)) 822: { 823: mismatch++; continue; 824: } 825: 826: if (code != opcode) 827: table68k[code].handler = opcode; 828: } 829: } 830: } 831: 832: void do_merges (void) 833: { 834: long int opcode; 835: int nr = 0; 836: mismatch = 0; 837: for (opcode = 0; opcode < 65536; opcode++) { 838: if (table68k[opcode].handler != -1 || table68k[opcode].mnemo == i_ILLG) 839: continue; 840: nr++; 841: handle_merges (opcode); 842: } 843: nr_cpuop_funcs = nr; 844: } 845: 846: int get_no_mismatches (void) 847: { 848: return mismatch; 849: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.